Home Explore Blog CI



git

5th chunk of `Documentation/git-push.adoc`
033818e88289f8b3fc7376fa5def91c3338bc343e302df720000000100000fa5
 semantics may change as we gain experience
with this feature.
+
"--no-force-with-lease" will cancel all the previous --force-with-lease on the
command line.
+
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:
+
	git remote add origin-push $(git config remote.origin.url)
	git fetch origin-push
+
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.

-f::
--force::
	Usually, the command refuses to update a remote ref that is
	not an ancestor of the local ref used to overwrite it.
	Also, when `--force-with-lease` option is used, the command refuses
	to update a remote ref whose current value does not match
	what is expected.
+
This flag disables these checks, and can cause the remote repository
to lose commits; use it with care.
+
Note that `--force` applies to all the refs that are pushed, hence
using it with `push.default` set to `matching` or with multiple push
destinations configured with `remote.*.push` may overwrite refs
other than the current branch (including local refs that are
strictly behind their remote counterpart).  To force a push to only
one branch, use a `+` in front of the refspec to push (e.g `git push
origin +master` to force a push to the `master` branch). See the
`<refspec>...` section above for details.

--[no-]force-if-includes::
	Force an update only if the tip of the remote-tracking ref
	has been integrated locally.
+
This option enables a check that verifies if the tip of the
remote-tracking ref is reachable from one of the "reflog" entries of
the local branch based in it for a rewrite. The check ensures that any
updates from the remote have been incorporated locally by rejecting the
forced update if that is not the case.
+
If the option is passed without specifying `--force-with-lease`, or
specified along with `--force-with-lease=<refname>:<expect>`, it is
a "no-op".
+
Specifying `--no-force-if-includes` disables this behavior.

--repo=<repository>::
	This option is equivalent

Title: Git Push Force and Lease Options
Summary
The git push command has options to control forced updates, including --force, --force-with-lease, and --force-if-includes, which allow for overwriting remote refs with caution, ensuring that local changes are based on the most recent remote version, and preventing loss of commits due to background updates or implicit fetches, with various usage scenarios and safety considerations to mitigate potential risks.