Johannes Schindelin <Johannes.Schindelin@xxxxxx> writes: > I wonder whether the --force-with-lease option would benefit (and counter > the "unsafe because of behind-the-back operations" argument) from doing > some kind of "reverse pull --rebase". > > In other words, --force-with-lease could verify that the upstream branch > has no commits that weren't seen in the current branch's reflog, i.e. that > `git rev-parse HEAD@{upstream}` is identical to `git merge-base > --fork-point HEAD HEAD@{upstream}`. > > The assumption would be that you typically want to push with a lease only > when following the `pull --rebase` workflow. Meaning that you would only > want to force-push when your local branch had the upstream branch > integrated at some stage [*1*]. I suspect that the problem "--force-with-lease" wants to solve does not even appear in "pull --rebase" workflow, but let me think aloud to see where this leads, as the idea sounds interesting, even though I may have misunderstood what you meant by the above. If you do a "pull --rebase", you first rewind to the upstream and then reapply your changes on top, meaning that the result would normally be based on what was once at the tip of the upstream and should fast-forward. The only situation that a result of "pull --rebase" needs a non-ff push is when somebody else pushed there in the meantime, adding commits that you haven't seen yet. And you do not want to force your push to lose their work with "--force", with or without any lease. It does not change if you do an extra "fetch" to update the tip of your remote-tracking branch with their work. Using the lazy "--force-with-lease" is a wrong thing to do here, of course, but using any "--force", with or without lease, is _unnecessary_ with "pull --rebase". The safety afforded by the bog standard push that requires fast-forward is sufficient. And the above will equally apply to a non rebasing "pull". The problem "with-lease" part tries to solve is when you are actively rewinding the history of the upstream. Your upstream may look like: o---A---B---C and you fetch, squash B and C into one with some changes, to come up with a local history: BC / o---A---B---C and try to replace the upstream's tip (which is _supposed to be_ at C) with BC; the resulting history leading to BC is supposed to be a replacement of the upstream's history, and that is true only when the upstream's tip is still at C when you do your push. If somebody else built D on top of C and pushed there, that would no longer be true and you'd end up losing it by replacing the upstream's tip with your BC. Before the "with lease" option, when you want to fix the "---B---C" segment of the history that is already published, the only way to replace it with a single commit BC was with "--force" and there is no mechanism other than inter-developer coordination to make sure nobody will push D on top of C that will be lost with your forced push. "push --force-with-lease=<ref>:C BC:<ref>" is meant to be a solution for that issue.