I have been in active software development for the better part of the last year and a half. For the majority of that period, I've come to appreciate the power of git, especially since the onset of the pandemic, where I've been working remotely 90% of the time, the technology has been very crucial in the development of my career.
The aim of this post is to highlight some of the common git commands that I use on a daily, which I'm sure most of you reading this will apply at some point or do also apply. The post is also meant to deconstruct the notion that git is complicated. Hopefully, you'll gain new insights into it. Let's dive in...
This article is divided into four parts:
*Disclosure: I only recommend products I would use myself and all opinions expressed here are my own. This post may contain affiliate links that at no additional cost to you, I may earn a small commission.
Definition of terms
Before we move to the commands, it's important to familiarise ourselves with common terms used in the git world.
Let's have a look at some of them.
- Git - it is a distributed version control system for tracking any set of files, for coordination among developers. Basically put, it is like a savings program for your project. It enables tracking and logging the changes you make to your file or file sets over time, a version-control system gives you the power to review or even restore earlier versions by taking snapshots of every revision in your project. You can access these versions to compare and revise them when the need arises.
- Git repository hosting service - these are third-party web applications that wrap and enhance a version control system. An example of popular ones are; Github, Bitbucket, Gitlab. Many people confuse these to be one and the same thing with git. However, they are completely different. So, are they much more closely connected than Java and JavaScript? Yes, git is the underlying technology that platforms such as Github use to manage repositories. For a more detailed explanation on this, check out this article.
-
Git branch - a branch represents an independent line of development on a project. For example, if you're working on a feature that involves creating an admin dashboard, you may choose to create a branch called
dashboard
in which you work on all the dashboard logic. - HEAD - When working with Git, only one branch can be checked out at a time - and this is what's called the "HEAD" branch. Often, this is also referred to as the "active" or "current" branch. Git makes note of this current branch in a file located inside the Git repository, in .git/HEAD. (This is an internal file, so it should not be manually manipulated!). By now you may have noticed that the tree is the symbolic representation in git 😄.
Commands
-git init
- This command creates a new Git repository. It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository.
-git remote add origin {remote_url}
- connects a repo to a remote git URL. An example is;
git remote add origin https://github.com/tngeene/Dadjokes-app.git
-
git remote -v
- checks the remote URLs set on a particular repo. A repo can have more than one remote, say for example you're pushing the code to two platforms such as Github and Bitbucket -
git remote remove origin
orgit remote rm origin
- removes a remote- alternatively, you can use
git remote set-url origin {new.url.here}
this command automatically removes the old remote and assigns the new one. In our example above, you might realize you've made a mistake and set the wrong origin, using the second approach of removing an origin, (I won't delve into the first one since it's pretty straightforward), you can run this commandgit remote set-url origin https://github.com/tngeene/Bakery-template.git
and this will remove the previously specified url and set the new one.
- alternatively, you can use
-
git rm -r --cached .
- this command comes in handy when you want to untrack files, say you realized you would like to add it to the.gitignore
file when it was already tracked.- rm : remove command.
- -r : allows recursive removal.
- — cached : will only remove files from the index. Your files will still be there.
-
.
: untracks all files. You can untrack a specific file bygit rm -r --cached {path_to_ file}
-
git clone
- useful for getting the contents of a remote repo to your local machine. Usually used when you don't initially have the code. Example usage isgit clone {url_of_repo}
, for examplegit clone https://github.com/tngeene/fibonacci-sequence-react.git
-
git fetch
- really only downloads new data from a remote repository - but it doesn't integrate any of this new data into your working files. Fetch is great for getting a fresh view of all the things that happened in a remote repository. -
git pull
- in contrast, is used with a different goal in mind: to update your currentHEAD
branch with the latest changes from the remote server. This means that pull not only downloads new data; it also directly integrates it into your current working copy files. This has a couple of consequences:- Since
git pull
tries to merge remote changes with your local ones, a so-called "merge conflict" can occur.
- Since
Sytntax to use
git pull {remote_branch_name} {feature_branch_name}
- for example git pull origin master
One can use git pull —set-upstream {remote_branch_name} {feature_branch_name}
. This syntax avoids specifying the remote branch to update every time, for example, git pull —set-upstream origin master
will allow you to just type git pull
once you've checked out in the master branch.
-
git push
- pushing the code that's in your local machine to a remote branch. The syntax is the same as the git pull command highlighted above.
A thing to note about this is that for an initial repo, especially if it was initialized with a README file, it might bring in errors such as the remote having contents you do not have. Another one could be that the repo has unrelated histories. So before you push code make sure to first pull from the remote by specifying git pull origin master —allow-unrelated-histories
-
git branch
- allows one to create a new branch. The syntax for this is,git branch -f {branch} {start_point}
.
git branch - f updates master
-
git checkout
The git checkout command lets you navigate between the branches created by thegit branch
command. For example, if we would like to navigate to the updates branch created above, we would simply rungit checkout updates
. Something to note when we're checking out is to make sure we've committed the changes we were working on in the branch we're checking out from.- Using the
git checkout
command, one can also create a new branch and checkout to it immediately, all using one command! So how do we go about this, you might ask. Well, simply typegit checkout -b {branch_name}
while in the current working branch. In our case above,git checkout -b updates
. This will automatically merge all the existing changes in your current branch into the newly created branch.
- Using the
-
git add
- now that you've finished working on all the cool stuff you've been working on, you'll want to push them to the remote origin we set with thegit add remote origin
command. Thegit add
command is part one of that process. This command adds a change in the working directory to the staging area. It tells Git that you want to include updates to a particular file in the next commit. There are two approaches to adding files that you want to push to the remote.-
git add .
This command adds all the changes you've made to be included when you push them to the remote. The.
at the end signifies that you want to stage all the files. -
git add {path_to_file_you_want_to_stage}
- this command lets you specify which updates you'd like to be staged for commit. For example one might only want to update the settings file, you would only need to typegit add ./settings.py
-
-
git commit
- finally that you've added all your changes you will want to save them to be included once you decide to push to the remote repo. This command saves the changes to your local machine.- The syntax for this commit involves including a message to describe what changes you've been working on, for example after working on a bug that fixes the login logic on a form, one might choose to commit it using this
git commit -m "fixed email validation on login API"
The -m flag denotes message
- The syntax for this commit involves including a message to describe what changes you've been working on, for example after working on a bug that fixes the login logic on a form, one might choose to commit it using this
It is important to write informative commit messages so
those other people who are working on the branch know
exactly what you were working on(just as it's important to
use descriptive variable names 😉).
-
git merge
- after working on all the changes in your newly checked out branch, you might want to merge all the changes to the main branch before pushing them to the remote. After making a commit on the feature branch, run the commandgit checkout {branch_you_want_to_checkout_to}
and thengit merge {feature_branch_name}
. In our example above, if we want to merge changes we've made into the main branch, we would go through these steps
git checkout main
git merge updates
-
git log
- this command allows you to view information about previous commits. it simply shows the commits that lead up to the current state of the current working branch.
Reverting to a previous commit.
Often times you may realize that you made a mistake and would like to roll back to a more stable version of the project. Luckily, git offers solutions to this problem. We can choose to either use git revert
or git reset
commands. For the purposes of this guide, I'll go with git revert
as I have more experience using it. However, for in-depth analysis and comparison of both commands, you can have a look at this article from atlassian.
The first step in rolling back is to identify at which point you'd like to go back. For this, we'll use our friend, git log
Notice the ordering of the commit history, with the "HEAD" being the first one on the list. If we want to go back to the commit with the message "reverted to ssr", we would run
git revert --no-commit 4eab63b2..HEAD
git commit
This will revert everything from the HEAD back to the commit hash, meaning it will recreate that commit state in the working tree as if every commit after 4eab63b2 had been walked back. You can then commit the current tree, and it will create a brand new commit essentially equivalent to the commit you "reverted" to.
The --no-commit
flag lets git revert all the commits at once.
Note that we've used the commit hash of the commit above the one we'd like to roll back to.
There is of course more than one way to revert, but this is what works for me. Feel free to add to the discussion on best practices to revert in the comments.
Best Practices
While working with git, it vital to follow some practices, especially working with a team. The practices I'll mention are my personal preference and totally biased towards my own views.
Use Descriptive commit messages
It's important to let other developers working on the project on what exactly you've been working on. writing a commit message such as "fixed loader on landing page" instead of "landing page update" goes a long way in informing the code reviewers of what you've worked on.
Make Pull Requests
Once you've pushed your changes to Github if on a feature branch, remember to make a pull request(merge request in GitLab). This will notify project owners of a request to integrate your changes into the main branch and they can do a code review.
Write an informative pull request message.
Still, on the subject of pull requests, it's important to let code reviewers know why you'd like your code to be merged into the main branch. An example of a pull request message would go along the lines of;
This commit contains updates on the user registration logic
1. Fixed signup form validation by adding error handling
2. Added vee-validate on login and registration forms
3. Updated redirection on successful signup
4. Integrated social auth as a signup option (using google and Facebook)
Keep Commit Revisions minimal
As a minimalist, I believe that it's best to work on bits of the code and push them instead of making revisions on many files and pushing them at once. My case for this argument is that it provides for good tracking in case things break at some point, we can just roll back to the commit and undo the minor mistake made on a couple of files instead of multiple files, which can prove to be a nightmare.
That covers the end of this article. There's a ton of information on git, but for now, we'll only dive into the shallow end that is the very deep pool of git. I hope this piece helps someone and feel free to drop your thoughts. You can also check out my website or follow me on Twitter.
Include a gitignore
file
When working on a project, there are some directories and files you'd prefer git not to track as well as some files which are not recommended to be tracked, an example being the node_modules
files in node.js. This aids in reducing boilerplate code since the files are still going to be recreated in the other developer's machine. I found this interesting GitHub repo containing a list of popular .gitignore templates for most frameworks and languages.
Resources
This section highlights some useful resources to get you started with git. It includes videos, blog posts, and podcasts.
- Freecodecamp's Git and GitHub youtube course
- A collection of gitignore templates
- Ladybug podcast episode on git and github
- Devmountain's explanation on the difference between git and github
- The official git documentation
- Edureka's youtube git course
Sponsors
- Do you need a place to host your website or app, Digital ocean is just the solution you need, sign up on digital ocean using this link and experience the best cloud service provider.
- The journey to becoming a developer can be long and tormentuos, luckily Pluralsight makes it easier to learn. They offer a wide range of courses, with top quality trainers, whom I can personally vouch for. Sign up using this link and get a 50% discount on your first course.
- Scraper API is a startup specializing in strategies that'll ease the worry of your IP address from being blocked while web scraping. They utilize IP rotation so you can avoid detection. Boasting over 20 million IP addresses and unlimited bandwidth. Using Scraper API and a tool like 2captcha will give you an edge over other developers. The two can be used together to automate processes. Sign up on Scraper API and use this link to get a 10% discount on your first purchase.
Thanks for going through the article. I hope in one way or another, you have a better understanding of git. Cheers!
Top comments (11)
Thanks for sharing. I rarely use
git rm
- I usually userm
and commit. And I rename the path to something else if I need to keep it.I added to my notes regarding cached and -r flags though.
I don't need to use
git branch
for a new branch. Your usage ofgit checkout -b
is much more common and practical.And pro tip. I rarely use
add
if a file already exists...If i make file changes, then i do this for the directory (or use a dir name).
You can also check the comments in your commit message editor window if you need to see which paths are going to be committed. Or use
git status
before you commit.Here I commit changes to package.json and package-lock.json without using
add
but preventing changes in other files getting commited.this is a new way of looking at things. Really helpful. Thanks Mike.
That's a very nice list! The bit about descriptive commit messages and pull requests is especially important. It's not very nice navigating a codebase where half the commits are "updated stuff" and "implemented thingamajig".
Here's a couple of more commands if you want to show off a bit to other developers in your team (or maybe make your and your teams lives a bit easier 😄):
Comes in pretty handy if you're tired of having to write git checkout [branch] every time you want to change branches. Can just do git co [branch]. You can of course create aliases for other stuff like commit, etc.
Another cool command is rebase. Many people use it mainly for rebasing master onto a feature branch but you can also use it for cleaning up commits on your feature branch. Here's a pretty cool article showing how to do it.
Thanks! I didn't know this. I tried it out and works like a charm!
Just a query here. So we take out a branch from the 'main' as 'code fix'. Once done with the changes we would commit & push the branch to the repo. Checkout the 'main' branch and then merge the 'code fix' to the main
Am i saying this right or missing out on something?
Yeah, you're saying it right. But the appropriate way is to push it to the repo and wait for it to be merged. The only reason you'd merge locally is when you're working alone. But it's advisable that you push to the remote, once it's been merged then you can pull from the master.
Nice read.....you made it so easy to understand 😀
Useful list here for Git newbies and experienced users alike.
Very well explained Teddy. Nice one.
Nice one! You may be interested in this one as well as explaining some of the cool features behind git log/blame: dev.to/bmuskalla/git-archeology-1nl3
nice article...