What is the difference between these two git commands when force pushing changes?
git push -f origin branch
and git push origin +branch
If you're only pushing one branch, there is no difference.
git push -f origin branch
and
git push origin +branch
are exact equivalents. The difference arises when you're pushing more than one branch with a single git push
.
In a nutshell, the optional +
gives you finer control than -f
does: if you're pushing more than one ref at a time, the +
allows you to specify which of the pushed refs get force-pushed, whereas --force
(or -f
) applies to all the refs that are getting pushed.
git-push
man page tells youThe most basic form of git push
that involve one or more refspec(s) is
git push <repository> <refspec>...
The form that the <refspec>...
argument must satisfy is described in the git-push
man page thus:
<refspec>...
Specify what destination ref to update with what source object. The format of a `<refspec>` parameter is an optional plus `+`, followed by the source object `<src>`, followed by a colon `:`, followed by the destination ref `<dst>`.
So, just to be clear, the syntax for <refspec>
is
[+]<src>[:<dest>]
If :<dst>
is omitted, the same ref as <src>
will be updated... unless the remote.<repository>.push
entry (if any) in your Git config says otherwise.
Further down in the git-push
man page, you find
By having the optional leading
+
, you can tell Git to update the<dst>
ref even if it is not allowed by default (e.g., it is not a fast-forward.) This does not attempt to merge<src>
into<dst>
.
And still further down:
Note that
--force
applies to all the refs that are pushed, hence using it withpush.default
set tomatching
or with multiple push destinations configured withremote.*.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.ggit push origin +master
to force a push to themaster
branch).
Consider a local repo with two branches, master
and develop
, which you want to push (with a single git push
command) to an origin
remote.
git push origin master develop
will push both branches, but neither will get force-pushed.
git push origin +master develop
will push both branches, but only master
will get force-pushed.
git push origin master +develop
, conversely, will push both branches, but only develop
will get force-pushed.
git push origin +master +develop
will force-push both branches. It's an exact equivalent to git push -f origin master develop
.