Most applications cannot be successfully developed by one person - they usually require the collaboration of multiple developers working on and sharing the same code.
To make development easier and more robust - a version control system is needed that keeps track of all changes made by team members, even if some of them work with the same files.
Mastering Git commands is a must for successful collaboration and code delivery.
Today, we'll learn the 5 most important Git commands that every experienced developer should know.
We'll skip the basic commands like git config, git clone, etc. assuming you've already used them.
This command is extremely useful for applying the changes from the particular commit by creating a new commit on the active branch.
git cherry-pick <commit>
Imagine you are working with a component that displays a formatted date.
The component is ready, but it uses the native Date object in JavaScript:
const date = new Date("2020/12/31");
const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
// Output format: YYYY-MM-DD
console.log(formattedDate);
Suddenly you realize that someone in your team has just added a date handling library, say dayjs, and created a nice service that can be used in your component.
The code is not yet included in the main branch, it is still hanging in Github as Pull Request, but has been approved by your colleagues.
You can either wait for it to be merged, but what if the author is out of the office?
That's when cherry-pick comes into play.
Find the commit that adds the date handling service:
Copy its hash (from the URL), navigate to the terminal, and run the following command:
git cherry-pick bf6dd0785e7524314a1088a3fabf99b7296458c8
See that the command completed successfully:
The changes are applied and can be used immediately:
import { formatDate } from "./services/DateService";
const formattedDate = formatDate("2020/12/31");
// Output format: YYYY-MM-DD
console.log(formattedDate);
This command allows the current branch to be reset to the specific commit.
A file was accidentally added with the git add command and needs to be reverted
Run the following command:
git reset
A file was accidentally committed with the git commit command and needs to be undone, or you realized that commit was incomplete (we'll do a soft reset)
Run the following command:
git reset --soft HEAD^
Changes have been committed and you realize afterward that they are not really needed and have to be removed completely (we do a hard reset)
Run the following command:
git reset --hard HEAD^
Undoing a merge or rebase (hard reset)
Run the following command:
git reset --hard HEAD@{<step>}
Reset a local branch to the origin
From time to time I forget that I'm working on the main branch instead of the feature branch, and I commit my changes.
After I realize something is wrong, I reset my local main branch to the remote one with the following command:
git reset --hard origin/main
This command is used to join two or more branches together.
git merge <branch>
Imagine you are developing a feature on a separate branch and in the meantime. the main branch has been updated by a team member with the changes you need.
Then the main branch needs to be merged into the feature branch:
This creates a new merge commit containing the histories of both branches:
To ensure that the history is preserved, let's check the histories of both branches before merging.
main
feat/new-date-service
Note that the commit hashes are not changed after the merge (they are still the same ...7d5
and ...e92
for the "Add date service" and "Add needed changes" commits, respectively).
This command allows two branches to be merged together, just like git merge with some important differences.
git rebase <branch>
Rebase the feature branch to the main branch:
Rebase rewrites the commit history by creating entirely new commits for each commit in the original branch:
To ensure that new commits were created in the original branch, let's check the histories of both branches before rebasing.
main
feat/new-date-service
Note how the commit hashes for the original branch were changed after rebase (from ...17d
to ..ce6
for the "Add date service" commit).
One of the biggest advantages of using the rebase strategy instead of merge - is a clean commit history.
Unnecessary merge commits are skipped.
Merging and rebasing are both intended to apply changes from one branch to another, however, there are some important differences between the two commands.
They do their work in different ways.
Merge:
Rebase:
As mentioned earlier, one of the biggest advantages of using the rebase strategy instead of merge - is a clean commit history.
The second major advantage is a linear commit history, as seen in the image above, so it is easier to read the commit history with git log.
But you need to be careful when using rebase, as overwriting the project history can break your collaboration workflow.
Remember the Golden Rule Of Rebasing - never do it on public branches.
Read more about the differences between merge and rebase and the golden rule here.
This command tracks when Git references have been updated locally.
git reflog
Reflogs are useful in various Git commands, to specify the old value of a reference.
For example, HEAD@{5} means "where HEAD was five moves ago":
Let us try to read a reflog above:
Imagine that the rebase was done unnecessarily for some reason, so now it is necessary to restore the branch to its original state.
If you have the branch untouched on the remote, you can safely reset it:
git reset --hard origin/feat/app
But what if the branch exists only locally?
You can find a reference value before starting the rebase and reset to that point in time (HEAD@{3} for our example):
git reset --hard HEAD@{3}
Voila, you have just learned how to undo a rebase.
Git is an extremely powerful tool and offers us a lot of possibilities.
There are many more important commands that every developer should know, but today we learned about some of the most popular ones (I use almost all of them daily!).
I know all of these commands are overwhelming at first, but with a lot of practice, you will eventually get good at each of them.