This example demonstrates a rebase and how it differs from a merge. Understanding this is critical for working within most collaborative git workflows.
I have a local repo (named origin
) which I have forked from an upstream remote (named upstream
):
tylar@laptop:~/pyobis$ git remote -v
origin git@github.com:7yl4r/pyobis.git (fetch)
origin git@github.com:7yl4r/pyobis.git (push)
upstream git@github.com:iobis/pyobis.git (fetch)
upstream git@github.com:iobis/pyobis.git (push)
I have created a feature branch (named lint
).
I intend to submit a pull request so that my changes may contribute to the upstream
repo.
I have made a change on my fork|branch and the upstream remote has also had changes:
I want to pull the changes from upstream to my fork|branch so I can continue working with the upstream improvements included.
The first instinct is to git pull upstream master
, which will create the following:
THIS IS A PROBLEM.
The issue is not yet obvious, but when I later submit a pull request there will be merge conflicts. These merge conflicts are usually enough to kill the pull request completely.
If you have done this, you can undo it by going back to the commit before you did. Something like this:
# BE CAREFUL! These commands delete files and rewrite history.
git reset --hard b5d3ThisIsAnExampleCommitHash17ccb196be72d7
git push --force origin lint
Instead of adding the upstream changes after your branch's changes, you need to rewrite history so that the upstream changes come before your branch's changes.
To do this, use rebase
:
git rebase upstream/master
So great and clear explanation highlighting the difference between
merge
andrebase
. So simple and clear. Thanks a ton!