Fusion and relining serve similar goals, but accomplish them in different ways. The two help manage working with branch offices and collaborating with multiple people, but they are not interchangeable, and relining can be dangerous if not done correctly.
What’s wrong with relining?
Relining is very complicated, so understanding how git works under the hood is important if we are to make sense of it.
Git stores your code as a series of changes. You can think of it as a chain, working backwards. Each edit, or “commit”, refers to the ID of the previous commit and includes what has changed since the previous commit. This string is only stored on your computer; your Git client doesn’t talk to any other Git client unless it does a pull or push (pull is actually just a pull + merge with your local branch), and even then it doesn’t speaks only to a shared remote repository.
Branches are more complicated. Git only stores one thing when it comes to branches: the commit ID at the end of the branch. That way you can think of them as the playing head of a record player; you put the branch head in a specific position, and it comes back into the chain, “playing” your code and coming up with a final version. Each time you commit, your local git client will automatically move the playhead to the new commit.
If you wanted to merge the functionality into master, you would run:
git checkout master
git merge feature
This creates a new merge commit and if there are any conflicts you will have to resolve them manually. The git merge command moves the primary playhead to the new merge commit and removes the playhead from the feature, as it is no longer needed.
This method of merging code has three problems:
There may be changes to the main branch that the feature branch would like to include, especially if the feature takes a while to develop.
Having to go through the merge process every time you want to work with branches is boring.
The commit history is complicated, although this is largely a cosmetic issue.
Rebasing attempts to solve these problems, with varying degrees of success. Reload the changes where you started your branch. The entire branch is lifted and transported to the end of the current main branch, where it connects at the end. The main branch is left untouched and is free to continue to receive commits.
However, the commits are not actually moved, because the commits are immutable. Instead, they are copied, resulting in new validation IDs. Previous commits get stuck, hiding in your Git files but will never be seen again because the playhead has been moved elsewhere.
To run this process from the command line, you would run:
git checkout functionality
git rebase master
This opens the branch, checks out the current changes to the master, and then rebases the feature branch to the master branch.
At this point, the feature branch code is now more up to date, which is the only real feature of git rebase. Resetting does not merge the branches, because it does not create a merge commit or move the master playhead.
If you want to merge after rebasing, you need to run:
git checkout master
git merge feature
What would look like this, with the master read head replacing the function read head:
So rebasing does not solve the problem of managing merges, because you will have to merge at the end anyway to update the main branch. The actual merge command at the end should go smoothly, however, as the rebasing process forces you to “merge” the changes, which can still cause conflicts. And if you want to continue working on your branch, you still need to “merge” the changes.
Do not rebase shared branches
Remember how relining copies commits and leaves a stuck playhead? This is actually a major problem if you are working with shared code. Suppose you created the feature branch and passed it to your repository so that your colleagues can test it out. This is absolutely correct, but if any of them wanted to break away from your branch, when you finally rebased, you end up with this:
Your colleague’s feature2 branch now refers to an old chain of commits. Your Git client has no way of knowing, since the feature2 branch is stored on your colleague’s computer. They also have no way of knowing you’ve rebased until you push your changes.
When you rebased it did not copy the feature2 branch while copying all commits. Even if it could, it wouldn’t affect your colleague’s local Git repository, causing everything to get out of sync. The solution here would be to rebase feature2 onto the feature where it would be, but it’s complicated, even by Git standards, and it’s just a very simple example.
At the end of the line, do not rebase if you are not working locally.
When is it better to rebase rather than merge?
If your branch takes a long time to grow, rebasing fixes the problem of “branch syndrome”, where your code is too out of date with respect to the workmaster, and you need to update it to keep working. In general, you should try to avoid this problem as much as possible, but rebasing can fix it when it occurs.
If you are only making small incremental daily changes, you should instead work on a local master branch and use Extraction requests when you’re ready to apply your changes. These use the topical branches template, created specifically to store your code before it’s approved for a merge.
But, if you are working on a weekly period and are going to end up doing multiple pull requests and merging multiple times, you can work on your code a little longer, rebase locally for updates, and do a pull request at the end for reduce the amount of testing and talk to supervisors. Relining is mostly a local thing, so you can do it on your prep branches without waiting for approval.
If no one else depends on your branch, you can rebase before a branch merge to make the commit history clean and one-dimensional. However, one could argue that traditional merge, while certainly uglier, is easier to follow and debug, since merge commits are entirely non-destructive. Either way, the rebase should be done right before your changes are merged, otherwise you might run into the issue of updating Master before your changes are approved.