Very nice explanation. I will definitely use this one next time I have to explain rebase ;-).

However, what I was missing is a word on the trouble you can cause when rebasing already pushed commits.

The rebase itself technically removes your old commits and makes new commits identical to them, rewriting the repo's commit history. That means pushing the rebase to the remote repo will need some extra juice.

This has its reason. If there are several people working on the same branch, you are making changes that have not been pushed yet incompatible with the upstream branch for everyone else working on the branch. This means once you do this, everyone else has to pull with --force and reintegrate their changes (in the best case by rebasing themselves, in the worst case with much more complicated and tedius measures or having to recover "lost" commits from reflog if someone pulls with --force without care).

In the given example that clearly aims towards pull requests and single user WIP branches you might not get struck by this very often, but this can be a real problem.

Thus, my recommendation is always to use rebase as much as possible as long as you are not breaking the history for anyone else. This normally means that you shouldn't rebase commits you have already pushed or - if you do nevertheless - know exactly what the consequences are in your case and get consent of other people working on the branch if needed.

Very this. A simpler rule: just never use git push --force* except you're the one and only working on the branch and you're ready for consequences. I prefer periodical merges with master if the branch is already pushed, the history doesn't look as good as with rebase but OTOH it won't be messed up. Any usage of --force (both push and pull) can unexpectedly remove commits you don't want to be removed so just don't do it. Fortunately, it's relatively easy to restore them, read about git reflog.

That's pretty much the essence of what I wanted to say. Just wanted to point out that it is not the end of the world if you have to push with --force, you just need to know about the consequences and if it gets you into trouble.

But in general, I agree. In collaboration branches, you should not need --force in your all da work. I also prefer merging master (or an other parent branch) regularly to the topic branch and merging when ready with --squash and a proper message to remove WIP commits, but this is a topic that involves a lot of personal taste and philosophy, so discussion is difficult about this.

Thanks for the extra perspective! I work on many solo branch PRs myself so this kind of issue with rebases hasn't hit me that often. But there have been one or two moments where pushing rebased commits have caused issues with co-workers, and better communication with them was always how they would've been avoided.