Web lists-archives.com

Re: What's cooking in git.git (Jul 2017, #03; Mon, 10)

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:


and you fetch, squash B and C into one with some changes, to come up
with a local history:


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.