Git push rejected after feature branch rebase

The problem is that git push assumes that remote branch can be fast-forwarded to your local branch, that is that all the difference between local and remote branches is in local having some new commits at the end like that:

Z--X--R         <- origin/some-branch (can be fast-forwarded to Y commit)
       \        
        T--Y    <- some-branch

When you perform git rebase commits D and E are applied to new base and new commits are created. That means after rebase you have something like that:

A--B--C------F--G--D'--E'   <- feature-branch
       \  
        D--E                <- origin/feature-branch

In that situation remote branch can't be fast-forwarded to local. Though, theoretically local branch can be merged into remote (obviously you don't need it in that case), but as git push performs only fast-forward merges it throws and error.

And what --force option does is just ignoring state of remote branch and setting it to the commit you're pushing into it. So git push --force origin feature-branch simply overrides origin/feature-branch with local feature-branch.

In my opinion, rebasing feature branches on master and force-pushing them back to remote repository is OK as long as you're the only one who works on that branch.


Instead of using -f or --force developers should use

--force-with-lease

Why? Because it checks the remote branch for changes which is absolutely a good idea. Let's imagine that James and Lisa are working on the same feature branch and Lisa has pushed a commit. James now rebases his local branch and is rejected when trying to push. Of course James thinks this is due to rebase and uses --force and would rewrite all Lisa's changes. If James had used --force-with-lease he would have received a warning that there are commits done by someone else. I don't see why anyone would use --force instead of --force-with-lease when pushing after a rebase.


I would use instead "checkout -b" and it is easier to understand.

git checkout myFeature
git rebase master
git push origin --delete myFeature
git push origin myFeature

when you delete you prevent to push in an exiting branch that contains different SHA ID. I am deleting only the remote branch in this case.