If there is a tool or software that every software developer must know, it is GIT. Everyone will agree that we all struggle with it initially when we start learning it. So I’m here to ease the burden from the shoulders of the beginners, who are just starting with this amazing tool.
Let’s Git it!
We’ll be learning the following topics today:-
Now we know that you understand basic git usage. It’s time to use the most effective feature of git, branching. Branching is mostly used when we want to work on several parts/features of a project simultaneously and don’t want the work on one feature to affect others. Branches can be visualized in the following way:
For this tutorial, this is currently the branch structure that we’re having:
The default branch is called
master. To create a new branch, run the following command:
git checkout -b <branchName>
It creates a new branch and sets the HEAD to that branch (checkout). This is shorthand for:
git branch <branchName> git checkout <branchName>
We’ve created a branch named
Feature, after running the mentioned commands this will be the state:
We’re now at the head of the newly created
Feature branch. Now make some changes and commit again. The state of the repo will change to:
You can switch between branches by simply using the
git checkout <branchName>
Note:- You cannot switch between branches before committing the changes in your current branch.
After switching to the master branch, this will be the state:
Now let’s say we make 2 more commits in the master branch.
Now, what we’ll do is update the
Feature branch with the commits done in the
master branch. This way we’ll have all the updates of the master branch in the
Feature branch. First, checkout the
git checkout Feature
Now to have the commits of the master branch you need to merge master branch into the feature branch. In order to merge the branches, we’ve already checked out the feature branch, now just run the following command:
git merge master
After this, the text editor will pop-up and will ask you to write the merge commit message. Enter the message then save and exit the text editor.
Now, feature branch will also have the commits and the changes done in
C5 from master branch. Also, the new
C6 commit is the merge commit, for which you wrote the commit message.
Note:- The commits
C5 in the
feature branch are the same ones as the
master branch i.e the commit hashes do not change and if you delete any of the commits, it’ll be deleted from both the branches.
Bamm! Now you know the basics of branching and merging. Now it’s time to learn one more important technique, rebasing. But before that let us discuss something that we call as
Sometimes it may happen that you’ve created a new branch, say
sampleBranch, and changed the contents of a file in it, meanwhile, someone else working in the
master branch also changes the content of the same file. Now if you try to merge the
sampleBranch into master, you’ll get merge conflicts as git will get confused in which changes to keep and which ones to leave. In that case, you need to resolve the merge conflicts before committing the merge.
Rebasing helps in avoiding merge conflicts. So let’s learn how rebasing is done in git.
According to Git-tower:
In Git, the rebase command integrates changes from one branch into another. It is an alternative to the better known “merge” command. Most visibly, rebase differs from merge by rewriting the commit history to produce a straight, linear succession of commits.
Rebase is a better technique than merging because it doesn’t give you a merge commit, just the commits required.
As given by Atlassian, rebase can be visualised as follows:
From a content perspective, rebasing is changing the base of your branch from one commit to another making it appear as if you’d created your branch from a different commit. Internally, Git accomplishes this by creating new commits and applying them to the specified base. It’s very important to understand that even though the branch looks the same, it’s composed of entirely new commits.
Now let’s say we’re in this state:
C5, we’ve worked on the same files as
C4, and we want to merge the master branch into feature branch and bring the changes of
C4 into feature branch. Now if we do a merge, then there will be merge conflicts and we’ll be having a new merge commit
C6, containing the changes of all
C5, like this:
But we don’t want that, we want to reattach our
feature branch to the new root
C4, like this:
This can be done using the simple rebase command,
feature branch first and then run the following command:
git rebase master
Git might ask you to fix conflicts, this is how you can do it:
<<<<<<<<<<< HEAD use changeFromC4; =========== use changeFromC5; >>>>>>>>>>> Your Commit
Both the changes are in the same line in the same file, the upper one is done in
C4 and the lower one is done in
C5, now git is asking you which one to keep. A way to fix this is to include both, so you can delete all the lines from the »> to «<, and replace them with the correct code:
use changeFromC5 changeFromC6;
After fixing all the conflicts, add all the files you edited:
git add <files you edited> git rebase --continue
You might need to do this action multiple times until every merge conflict is resolved. In case you mess up things, you can always run the
abort command to start over:
git rebase --abort
Hurray! You now know rebasing as well (You’re a pro, I’m telling you already!). Now there’s one last technique that we need to learn, which is used a lot when contributing to open source projects, squashing.
It may happen sometimes that you’re working on a project and you’re committing a lot, even for a small change you are having a commit, now you have a finished project with more than 100 commits, which is not a good thing as it’ll be difficult for others and you as well to go through your commits and find the changes that you’re looking for. So git provides you a very good feature of merging commits known as squashing, it is similar to merging, the difference is that it’s used to merge commits, not branches. So without wasting any more time, let’s squash!
For this tutorial we’ll be working entirely in
feature branch, let’s say we’re in the following state:
And we want to squash
C6 into one commit, say
C7. We can do that simply by the following steps:
git log and copy the hash of the commit
git rebase -i <hash of C3>
This will open in a text editor:
pick <hash of C4> C4 pick <hash of C5> C5 pick <hash of C6> C6 # Rebase f181e0e..f9c96cf onto f181e0e (2 command(s)) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
Now keep the first commit and change the rest from
pick <hash of C4> C4 squash <hash of C5> C5 squash <hash of C6> C6 # Rebase f181e0e..f9c96cf onto f181e0e (2 command(s)) # ......
Save and exit the text editor. The rebase will run till the end and all the commits after C4 will get squashed into one.
After the rebase is done, the text editor will pop-up again, now you can write the commit message for the new commit
C7. The commits are now squashed.
Now if you want to push this to your remote repo, run the following command:
git push <remoteName> <branchName> -f
-f flag means force push.
Booyah! You now know how to use git, remember, this is just the beginning and only practice can help you learn git well. With this ends our git tutorial series Git it. We hope that you understood the concepts well.
If there’s still something that you think that is missing or needs to be modified, you can comment down below or let us know by raising an issue.