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 mainThis makes a new commit in
featurebranch let suppose it isg'which contains main commitscandd.Feature —- e-f-g-g' | Main -> a-b—-c–d
The above case is the
recursivemerge. If suppose there isn’t commitseandf, then merge just need to add commitscandd. The latter case is called thefast-fowardedwhere 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
mainchanges intofeaturebranch. - Add
git config --add branch.master.mergeoptions --ff-onlyorgit config --add branch.main.mergeoptions --ff-onlyand 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