git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: using --force-with-lease after git rebase

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 1, 2018, 01:19 UTC
Message-ID
<xmqqr2g5vbk4.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<CA+KyZp5Zv77idtpu9jtxDUyE9zPP8UN3LsQBG=M5yM2cnMFgVQ@mail.gmail.com>
Alexander Mills <alexander.d.mills@gmail.com> writes:
Show 18 quoted lines
> I have been confused about the need for --force-with-lease after rebasing
>
> Imagine I have a feature branch:
>
> git checkout --no-track -b 'feature' 'origin/dev'
> git push -u origin feature
>
> I do some work, and then I rebase against origin/dev to keep up to
> date with the integration branch.
>
> git fetch origin/dev
> git rebase origin/dev
>
> then I try to push to the remote
>
> git push origin feature
>
> but that is rejected, I have to do:

This all depends on how the "dev" branch at the "origin" remote relate to the branch at "origin" you are updating with the commit at the tip of the "feature" branch. Are you pushing to "feature" branch?

If so, then the rejection is very much expected. At this point, the histories of the "feature" branch at the "origin" remote is seeing would look like this:

    ---X---o---o---o---o---A
        \
         x---x---x---x---B

where (X) is where you started the old iteration of the "feature" branch forking off of the "dev" branch, (A) is the tip of that old iteration of the "feature" branch, and (B) is the tip of the new itertion of the "feature" branch you are trying to update with.

The "origin" repository does not know WHY B is not a fast-forward of A. The only thing it knows is that you are discarding the work done in commits (o) while attempting to publish commits (x). If it is intentional, then that's fine, but it does not know (x) are replacements for (o) due to rebasing, so it errs on the side of the caution.

With the "--force-with-lease=feature:A" option, you can tell the other side: "it is OK if this push does not fast-forward, as long as I am updating from A" [*1*].

"--fore-with-lease" without saying what the commit you are expecting to discard makes Git on the sending side _guess_. Depending on what you do locally, it can make a wrong guess, so I would not recommend such a use, but if you saw it succeed and if you did not lose commits at the "origin", then it may have guessed correctly ;-)

[Footnote]
*1* Telling what the value of 'A' is to the other side is important,
 as you are essentially saying that 'B' has everything you want to
 resurrect from 'A'.  Imagine that somebody else pushed to update
 "feature" at the "origin" remote from 'A' to 'C' (or if you did so
 and forgot about it) and then you tried to push 'B' after rebasing.
                             C
                            /
    ---X---o---o---o---o---A
        \
         x---x---x---x---B
 As far as you (who rebased) were concerned, 'B' is equivalent to
 (or "an improved version of") 'A' and you want the push that does
 not fast-forward to go through to replace 'A' with 'B'.  By telling
 "I am replacing A with B" (instead of saying "I am replacing
 whatever with B", which is what "--force" is), the receiving side
 at the "origin" repository can notice that there was another update
 by somebody else's push to the branch while you are preparing 'B'
 and the tip of "feature" is no longer at 'A', and reject the push
 in order to prevent you from losing the work between 'A' and 'C'.
Previous: brian m. carlson
Message 3 of 3 in “using --force-with-lease after git rebase”
  1. Alexander MillsOct 31, 2018
  2. brian m. carlsonNov 1, 2018
  3. Junio C HamanoNov 1, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.