I have to be honest, rebasing a branch for me was like a magic trick. I have never spent time to really study the correct mechanism of rebasing and I have always simply followed what git asked me to do after having fixed the conflicts when found.
But that’s definitely not the right way to work with a version control system. You have always to be perfectly conscious of what you are doing, because vcs are powerful but at the same time dangerous tools.
So I decided to focus on studying about this topic, and googling I found out this question can’t push to branch after rebase well replied by Trev Norris.
Updating from a Remote Repository
Starting from this example
to stay up-to-date with remote master
branch, the right workflow is
don’t use git pull
as wisely suggested in the post Git: fetch and merge, don’t pull.
Why? Because:
git pull
works like a magic button which does many things automatically (fetch
andmerge
) by itself and most of the time it properly works; but when it doesn’t, it’s often hard to figure out why;- by both fetching and merging in one command, your working directory is updated without giving you a chance to examine the changes you’ve just brought into your repository.
(for more informations, I strongly recommend to take a look at the post previously linked, because definitions and reasoning about branches are very interesting and well written)
So, starting with the first command:
it allows to get the changes from the remote repository into your local repository withouth touching your working tree at all. More in general, with that command you might get if there are remote changes without needing to switch from the devel0
branch. Furthermore, it’s a safety mechanism to make sure you don’t overwrite any un-stashed/committed changes.
If there are changes, after having analyzed the output message of git fetch origin
(Git: fetch and merge, don’t pull well explaines how do that), you can checkout on the master
branch:
and then you have to decide if you want to bring the changes from the remote branch into your working tree. So you might want to see what the differences are between the local branch and the remote one:
If you want to get the changes from the master
branch, you need just to merge the changes that you’ve just got from origin
Rebasing your Local Repository
After having merged the remote changes, you can start the rebase of the devel0
branch
where +
before devel0
allows to force a push to only one branch. This is necessary for git push
in this specific case because (quoting the push-manual page):
Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it.
and this is what exactly happens after a rebase, because the ancestors of the local branch change. So
This flag disables these checks, and can cause the remote repository to lose commits; use it with care.
So don’t use it for normal push…NEVER!!!
At the end, the history will be a thing like the following
Just in case your starting history was (thanks to Trev Norris)
and you need to rebase both devel0
and devel1
, after having rebased devel0
as previously described, you need to rebase devel1
following this workflow
and the final result will be
That’s all. But before thanks to
Happy hacking and GWH!!!