Merging and rebasing
Today,
I will be explaining git rebase, git merge, purpose for these and when to use these.
Both git rebase
and git merge
are used to integrate the changes of one branch to another branch
let’s suppose this is the scenario:
Feature —- e-f-g | Main -> a-b—-c–d
Now to have c,d commits in feature
branch, we have 2 options
-
Merge
git checkout feature && git merge main
This makes a new commit in
feature
branch let suppose it isg'
which contains main commitsc
andd
.Feature —- e-f-g-g' | Main -> a-b—-c–d
The above case is the
recursive
merge. If suppose there isn’t commitse
andf
, then merge just need to add commitsc
andd
. The latter case is called thefast-fowarded
where the commit history is linear and it doesn’t need to add a commit. In this casegit merge main // won't create a new commit but if we use `--no-ff` then it will create a new commit
To reset merge:⌗
git reset --hard HEAD~1
this command can be used to reset merge if the last commit is merge commit
or you can get the commit from git reflog
and do git reset --hard #commit
- Rebase
git checkout feature && git rebase main
This adds all the commits in main and then adds the latest commits of feature. Basically changes the parent of first different commit in the feature
branch and child of the last main
commit.
Feature e'-f'-g' | Main -> a-b—-c–d
To reset the rebase:⌗
git reset --hard ORIG_HEAD
Rebase stores the old state before rebase in ORIG_HEAD
or you can get the commit from git reflog
and do git reset --hard #commit
Feature —- e-f-g | Main -> a-b—-c–d
If c
and e
has same changes and the committer info is different basically if both the checksum is same then in git rebase main feature
, the final history of feature
will look like
a->b->c->d->f->g. It skips the e
in the feature branch.
If git rebase
doesn’t take merge commits, then mention -p
to take merge commits into consideration while rebasing
Pro’s and Con’s of each:
Rebase pros are the commit history will be linear so all the commits of a feature will be present at one place.
Cons are as the commit history changes, the will be problem of reaching a commit and the resolving conflicts will be a problem
Merge pros and cons are the vice-versa of rebase.
So rebase will be useful you are IC(individual contributor) and merge will be useful if there are many people.
Squash:⌗
For squashing, you can use git rebase -i HEAD~3
and have s for the commits to squash it.
Best solution:⌗
It is best to use rebase on the feature
branch (i.e while getting the latest changes) and use merge in main
branch
- Use rebase while pulling the
main
changes intofeature
branch. - Add
git config --add branch.master.mergeoptions --ff-only
orgit config --add branch.main.mergeoptions --ff-only
and squash the feature commits before merge
You can get the best of both worlds: rebase local changes before pushing to clean up your work, but never rebase anything that you’ve pushed somewhere.
There is --onto
flag in git rebase
which is much useful. In git rebase --help
, it has been explained clearly. For real case scenario -> https://stackoverflow.com/questions/51194261/git-rebase-with-merged-commits
This repo has all the cases using git merge
and git rebase
. Use git reflog
and git log --graph
to understand the commit history