git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* using --force-with-lease after git rebase
@ 2018-10-31 19:13 Alexander Mills
  2018-11-01  0:58 ` brian m. carlson
  2018-11-01  1:19 ` Junio C Hamano
  0 siblings, 2 replies; 3+ messages in thread
From: Alexander Mills @ 2018-10-31 19:13 UTC (permalink / raw)
  To: git

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:

git push --force-with-lease origin feature

why is that? Why do I need to force push my feature branch to the
remote tracking branch after rebasing against the integration branch?

-alex

related question:
https://stackoverflow.com/questions/52823692/git-push-force-with-lease-vs-force/53042745#53042745



-- 
Alexander D. Mills
¡¡¡ New cell phone number: (415)730-1805 !!!
alexander.d.mills@gmail.com

www.linkedin.com/pub/alexander-mills/b/7a5/418/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: using --force-with-lease after git rebase
  2018-10-31 19:13 using --force-with-lease after git rebase Alexander Mills
@ 2018-11-01  0:58 ` brian m. carlson
  2018-11-01  1:19 ` Junio C Hamano
  1 sibling, 0 replies; 3+ messages in thread
From: brian m. carlson @ 2018-11-01  0:58 UTC (permalink / raw)
  To: Alexander Mills; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 2025 bytes --]

On Wed, Oct 31, 2018 at 12:13:06PM -0700, Alexander Mills wrote:
> 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:
> 
> git push --force-with-lease origin feature
> 
> why is that? Why do I need to force push my feature branch to the
> remote tracking branch after rebasing against the integration branch?

When you perform a push to an existing branch, Git checks to make sure
that the push is a fast-forward; that is, that your changes are a strict
superset of the commits that are in that branch.  When you rebase a
branch, you rewrite the commits and their object IDs (their hashes).
Since you've rewritten some of the commits that were on the version of
your branch that you pushed to the server, the commits you want to push
are no longer a strict superset, and Git requires a force push.

This provision is in place to prevent data loss.  For example, if you
and a colleague are both collaborating on a branch that isn't rebased,
you would want to avoid pushing changes that overwrote those that your
colleague had made.  Git making your push fail is its way of helping
you realize that there are changes you have not included and making you
decide how you want to handle them.

You strictly do not need to use --force-with-lease; you could just use
--force instead.  But using --force-with-lease over --force when
possible ensures that you are overwriting what you think you're
overwriting, and not additional working changes that someone else has
made, so it's a good practice.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 868 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: using --force-with-lease after git rebase
  2018-10-31 19:13 using --force-with-lease after git rebase Alexander Mills
  2018-11-01  0:58 ` brian m. carlson
@ 2018-11-01  1:19 ` Junio C Hamano
  1 sibling, 0 replies; 3+ messages in thread
From: Junio C Hamano @ 2018-11-01  1:19 UTC (permalink / raw)
  To: Alexander Mills; +Cc: git

Alexander Mills <alexander.d.mills@gmail.com> writes:

> 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'.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-11-01  1:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-31 19:13 using --force-with-lease after git rebase Alexander Mills
2018-11-01  0:58 ` brian m. carlson
2018-11-01  1:19 ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).