Merge branch 'jj/log-doc' into maint
[gitweb.git] / Documentation / git-push.txt
index f7dfe48d2813324e1a699efa530afe8974d7c400..9eec74091097c0ea5c9fea69a09eb63e3cebd8d9 100644 (file)
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
           [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream]
+          [--force-with-lease[=<refname>[:<expect>]]]
           [--no-verify] [<repository> [<refspec>...]]
 
 DESCRIPTION
@@ -120,7 +121,7 @@ already exists on the remote side.
 --follow-tags::
        Push all the refs that would be pushed without this option,
        and also push annotated tags in `refs/tags` that are missing
-       from the remote but are pointing at committish that are
+       from the remote but are pointing at commit-ish that are
        reachable from the refs being pushed.
 
 --receive-pack=<git-receive-pack>::
@@ -130,21 +131,75 @@ already exists on the remote side.
        repository over ssh, and you do not have the program in
        a directory on the default $PATH.
 
+--[no-]force-with-lease::
+--force-with-lease=<refname>::
+--force-with-lease=<refname>:<expect>::
+       Usually, "git push" refuses to update a remote ref that is
+       not an ancestor of the local ref used to overwrite it.
++
+This option bypasses the check, but instead requires that the
+current value of the ref to be the expected value.  "git push"
+fails otherwise.
++
+Imagine that you have to rebase what you have already published.
+You will have to bypass the "must fast-forward" rule in order to
+replace the history you originally published with the rebased history.
+If somebody else built on top of your original history while you are
+rebasing, the tip of the branch at the remote may advance with her
+commit, and blindly pushing with `--force` will lose her work.
++
+This option allows you to say that you expect the history you are
+updating is what you rebased and want to replace. If the remote ref
+still points at the commit you specified, you can be sure that no
+other people did anything to the ref (it is like taking a "lease" on
+the ref without explicitly locking it, and you update the ref while
+making sure that your earlier "lease" is still valid).
++
+`--force-with-lease` alone, without specifying the details, will protect
+all remote refs that are going to be updated by requiring their
+current value to be the same as the remote-tracking branch we have
+for them, unless specified with a `--force-with-lease=<refname>:<expect>`
+option that explicitly states what the expected value is.
++
+`--force-with-lease=<refname>`, without specifying the expected value, will
+protect the named ref (alone), if it is going to be updated, by
+requiring its current value to be the same as the remote-tracking
+branch we have for it.
++
+`--force-with-lease=<refname>:<expect>` will protect the named ref (alone),
+if it is going to be updated, by requiring its current value to be
+the same as the specified value <expect> (which is allowed to be
+different from the remote-tracking branch we have for the refname,
+or we do not even have to have such a remote-tracking branch when
+this form is used).
++
+Note that all forms other than `--force-with-lease=<refname>:<expect>`
+that specifies the expected current value of the ref explicitly are
+still experimental and their 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.
+
 -f::
 --force::
        Usually, the command refuses to update a remote ref that is
        not an ancestor of the local ref used to overwrite it.
-       This flag disables the check.  This 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.
+       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.
 
 --repo=<repository>::
        This option is only relevant if no <repository> argument is