Lets work this through.
There are 3 repositories: Your local clone, upstream, your fork (origin to your local clone)
After step 2, they look something like this:
upstream
o---o---o
a b c
fork
o---o---o
a b c
local
o---o---o
a b c
After step 5, the repos look something like this:
upstream
o---o---o---o---o
a b c d e
fork
o---o---o---o---o---o
a b c f g h
local
o---o---o---o---o---o
a b c f g h
That is, upstream has new commits d
and e
, and you've made new commits f
, g
and h
Now, you do git pull --rebase upstream master
The repositories now look like this:
upstream
o---o---o---o---o
a b c d e
fork
o---o---o---o---o---o
a b c f g h
local
o---o---o---o---o---o---o---o
a b c d e f' g' h'
Where f
and f'
are not the same commit - f'
is supposed to be equivalent to f
, but it has a different parent.
You can see here, that local has a different history now to fork; pushing to it isn't simply a case of adding new commits. Both think a different commit comes after c
, and the two branches do not converge; if you added all the commits, you'd end up with this graph:
,-----------o---o---o
| f g h
o---o---o---o---o---o---o---o
a b c d e f' g' h'
And what would be the current HEAD? h
or h'
? Neither preserve the history of the other.
You could merge these, but that would be wrong because you have equivalent changes in f
and f'
, g
and g'
etc.
You could do
git push -f
This would throw away f
, g
and h
from fork and make it look like local (you'd have f'
, g'
and h'
still), which is probably fine if no one else has cloned from fork
At step 6, instead of doing the rebase, you could have done
git pull upstream master
Which would have resulted in a merge, so the repos would look like this:
upstream
o---o---o---o---o
a b c d e
fork
o---o---o---o---o---o
a b c f g h
local
,---o---o---o---,
| f g h |
o---o---o---o---o-------o
a b c d e m
Where m
is a merge commit. This could then by trivially pushed to fork because it's just adding extra commits.
If you're planning to issue a pull request to upstream, though, maybe better not to merge their changes in, and let them pull and handle the merge.