Getting started with Git - Part 5 - Protecting Branches


You now have a solid foundation of the core concepts of Version Control with Git. We already have the basic workflow drilled in. This final part will cover a few important concepts that any Git master should know. Let's get started.
Protected Branches
Go ahead and fork and the
repository we'll be using. As we've done this a bunch of times now, there shouldn't be any hiccups.
Inside SmartGit's log view, right click on the
done for part 5
commit and select Reset
.
We've tried resetting in
part 1, this time we will do a
soft
reset. In a soft reset, the changes made after the commit that we've reset to, are not discarded but staged for the next commit.
We can see that the remote
master
branch is now ahead of our local branch. Push the master
branch as we have reset the local branch to a previous commit.
SmartGit will prevent the operation, warning us that the push operation might result in commits being overwritten.
Go ahead and modify the setting as told in the dialog box. We will, for once, ignore SmartGit's warning.
Note: You can also do this from the command line by running
git push -f origin master
. The flag -f
or --force
forces the commit, overwriting the remote branch if needed.
Try to push from SmartGit again. SmartGit will ask for a confirmation, informing that the push will replace the remote branch.
The push, however, will still not succeed.
Why did the push fail even when we force it?
The
master
branch on Gitlab is "protected" by default. Any destructive operation on the remotemaster
will fail.
You can check these settings in the Repository
section in Settings
on the repository page on Gitlab.
Making
master
a protected branch is considered a best practice. You may chop and slice the other branches as you like, but you never cut-off the trunk (aka the master
branch) of the tree.
By doing so, we ensure that, there will always be a way, to trace/find any commit pushed to the remote master.
Preventing overwrites is not the only utility of branch protection rules. You may also, disable pushing to a branch (forcing the use of pull requests), require code reviews before merging etc. These features can be further explored in the repository settings in Gitlab.
Note: Github can also be configured to follow the branch protection rules from the Settings
pane in the repository. However, branch protection is disabled by default.
But what if I really want to remove a commit? Simple, we accept the faulty commit and do another commit after that, reverting the changes made in the faulty commit.
Reverting commits
Start with a pull operation. The local branch should now be in sync with the remote. Right click on the update README.md
commit and select Revert
. This will create a revert
commit, which is an inverse of the faulty commit, undoing the changes made in the previous commit.
We can now push the local branch. Gitlab accepts the push with the reverted commit.
Think of
reset
as the sneaky way to undo changes, and revert
as the upfront way. Revert does not rewrite history, but alters the current state by making a new commit.
Rebasing
Apart from Merging, there is another way to incorporate changes from a branch to another. Instead of making a merge commit, a rebase "moves" the branch itself, changing the commit that it emerges from to a different commit.
Confused yet ?
Consider this scenario, you're working on the dev
branch and a critical bug in the previous release is discovered. This bug, as best practices dictate, is fixed in master
. However, if the bug also affects dev
, a merge commit will be made, merging from master
to dev
. Also, we've already learnt that at some point in the future dev
should be merged back into master
.
Here's what that looks like.
- bug fix in
master
- a bootstrap (feature) commit in
dev
- a merge from
master
todev
- another feature commit in
dev
- merge from
dev
tomaster
This process leads to a non-linear commit history polluted with several merge commits.
Let's try rebasing instead and see if we can do better.
-
Reset
master
toRevert "update README.md"
. -
Create a
dev
branch and make a commit in it. -
Checkout master and make a commit in it.
-
Checkout
dev
again and make a commit.
The changes made in these commits don't matter. Making changes in the
README.md
file for this is a good idea.
This is what the commit log should look like. We have re-created the same scenario, with an important commit in master
that's needed in dev
.
With dev
branch checked-out. Right-click on master
and select Rebase HEAD (dev) to
.
Let's go ahead with the green button !
This gives a cleaner commit log. It looks like the
dev
branch has been cut off a different commit than it was previously. The dev
branch is now made up of entirely new commits.
The rebase operation moved the entire
dev
branch. Previously,dev
originated fromRevert "update README.md"
. But now, it originates fromadd intro in readme
.
Rebasing is a great option, but only for local, non-public branches as it rewrites all the commits made in a branch.
Simpler language: Make sure that the dev
branch (which we moved) is a local branch, not connected to a remote before trying a rebase operation.
Cherrypicking commits
In the dev
branch, open package.json
and add a line, "private": true
. Commit this change.
{
"name": "antenna",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "^4.15.2",
"socket.io": "^1.7.3"
},
"scripts": {
"start": "node index.js"
}
}
Quick question !
What do we do if we need this commit in
master
?
Simple, we'd merge from
dev
tomaster
.
But, what we we only need this commit, and not the previous two commits (bootstrap.css) ? Maybe, the feature added in those commits is not complete yet, but the update package.json
commit is needed in master
right now?
Cherry picking
Cherry picking allows us to merge a single commit from a branch to another. With master
checked out, right click on update package.json
and select Cherry-Pick
The
Cherry-Pick & Commit
option will commit the changes (made in this commit) into master
. The Cherry-Pick
option will bring the changes to the Working Tree
from where, you can modify or add more changes before making a commit in master
.
As simple as picking cherries!
I hope this small series helped you in some way with Git. There is never a single way to do something with Git. Keeping learning and keep committing.
What next?
Well, stay tuned for upcoming articles. You may contact us for your software and consultancy requirements.
© 2025, Attosol Private Ltd. All Rights Reserved.