I have been using Merging heavily on master branch. But recently for a feature development in my situation merging seemed complicated for the project history. I came across Rebasing which solves my problem. I also came across the golden rule of rebasing while solving the problem.
I also used Stashing at times, it worked, but I feel like the same thing could have been achieved with merging as well.
Although I use these commands, I feel like if someone can explain the conceptually outstanding facts/rule about these three commands it would help me to get a clearer understanding. Thanks.
Stashing is very different, in that it essentially sets aside your changes for your later. Useful if you're in the middle of something and you have to jump onto something else and switch branches.
Merging and rebasing achieve the same thing in the end - combining changes into one branch.
The difference is that resolving the conflict inline effectively makes it as though the conflict never happened, because you're editing the file again to incorporate the change that caused the conflict.
That can be useful when you're looking back at the changes later.
The caveat, as you alluded to, is that rewriting history makes it hard or impossible to collaborate with others on that particular branch.
A series of merges from a long-standing feature branch can be quite hard to follow when looking at the graphs or visual representations from tools like gitg.
With rebases, it's much easier to follow the changes visually. It can also help when you're using tools like git-bisect to find the origin commit of bugs, as the branches are more straightforward to traverse.
Choosing which to go for depends on a few things.
Personally, I rebase and rebase often if I'm on a short-lived feature branch that I'm working on alone. Otherwise it's a merge.
There is a situation where you might have no choice to rebase - if you started your branch from the wrong point. For example, you may have had a particular feature checked out and began working on something else. That something else might be required to be merged and deployed before the feature it's based on. At this point, rebasing your changes onto a different branch will allow you to get that feature released independent of the other.
When you are merging a rebased branch back into master, that is still a merge, even if the history is linear. You may see a message in git telling you it did a "fast forward" merge. That means it merely moved the reference "master" to its new position. You can tell git not do this, and create a merge commit anyway, with the --no-ff
flag on the git merge command.
Linear history:
* HEAD, master, your_branch: your last commit
|
*
|
*
|
*
|
*
|
* previous master: where master was when you rebased
rebased history with a no-ff merge commit:
* HEAD: merge branch your_branch into master
| \
| * your_branch the last commit in your branch
| |
| *
| |
| *
| |
| *
|/
* previous master: the starting point of your branch