It will overwrite the tree on remote as long as remote hasn't changed since you last fetched it. It doesn't always work, particularly if you have a tool which continuously fetches remote, like an IDE configured to do so such as VSCode. In that case, you will have fetched the other person's changes, and --force-with-lease will happily blow-away anything on remote that might not be in your tree yet.
my flow is (on my-branch with no one else's commits)
* push some commits up to my remote branch
* git fetch
* git rebase master/main to get the latest stuff
* add changes on my-branch that use new stuff from master/main
* git push --force-with-lease to my remote branch - this fails if you don't use some version of force since my most recent commit is based on a commit (from master) not on the remote branch
I don’t get why everybody wants to rebase their topic branches. Just use merge, come on. If you want a „clean“ commit history on main/master do a squashed merge into main at the end.
This way we never had to force anything on the remote.
I rebase on my topic branches because then my edits are neatly stacked on top of the other branch, so I can re-arrange things more easily. Why would I want a weird commit with a bunch of work I didn't do on the topic just smooshed into the middle of my well-crafted series of commits?
Why would you have to force anything with rebase? you rebase your feature branch against main to rewind it on top of it and clean up history so you can do a clean fast forward merge. Squashing is bad for anything non trivial, you want small independent commits: easy to review, easy to revert, easy to blame if something goes wrong.
As soon as you pushed your branch to remote (which I tend to do for backup reasons especially after working hard on a solution) rebase only means trouble.
Not if it's the remote for your own dev branch. It only matters if the remote branch is being (actively) used by other people.
Unfortunately I've met far too many who have your "remote" superstition. I remember arguing this exact point in my last gig, when someone was mad at me for force pushing my own remote branch that nobody else was using nor should have been.
Or you mean that a mistake where you accidentally push to someone else's branch?
The default model that public github uses is good for that: everyone works on their own fork of the repo, and makes pull requests to the shared repo. Nobody pushes directly to the shared repo.
A general note on safety: supplying this option without an expected value, i.e. as --force-with-lease or --force-with-lease=<refname> interacts very badly with anything that implicitly runs git fetch on the remote to be pushed to in the background, e.g. git fetch origin on your repository in a cronjob.
The protection it offers over --force is ensuring that subsequent changes your work wasn’t based on aren’t clobbered, but this is trivially defeated if some background process is updating refs in the background. We don’t have anything except the remote tracking info to go by as a heuristic for refs you’re expected to have seen & are willing to clobber.
If your editor or some other system is running git fetch in the background for you a way to mitigate this is to simply set up another remote:
Now when the background process runs git fetch origin the references on origin-push won’t be updated, and thus commands like:
git push --force-with-lease origin-push
Will fail unless you manually run git fetch origin-push. This method is of course entirely defeated by something that runs git fetch --all, in that case you’d need to either disable it or do something more tedious like:
git fetch # update 'master' from remote
git tag base master # mark our base point
git rebase -i master # rewrite some commits
git push --force-with-lease=master:base master:master
I.e. create a base tag for versions of the upstream code that you’ve seen and are willing to overwrite, then rewrite history, and finally force push changes to master if the remote version is still at base, regardless of what your local remotes/origin/master has been updated to in the background.
Alternatively, specifying --force-if-includes as an ancillary option along with --force-with-lease[=<refname>] (i.e., without saying what exact commit the ref on the remote side must be pointing at, or which refs on the remote side are being protected) at the time of "push" will verify if updates from the remote-tracking refs that may have been implicitly updated in the background are integrated locally before allowing a forced update.
The existence of such a complicated workaround mainly serves as an official confirmation that you should just turn off auto fetch or not use force-with-lease. I use PyCharm's Update Project to fetch all branches at once on demand, so I will always get anyone's changes to my branch at the same time I fetch.
It will overwrite the tree on remote as long as remote hasn't changed since you last fetched it. It doesn't always work, particularly if you have a tool which continuously fetches remote, like an IDE configured to do so such as VSCode. In that case, you will have fetched the other person's changes, and --force-with-lease will happily blow-away anything on remote that might not be in your tree yet.