47

What is the difference between these two git commands when force pushing changes?

git push -f origin branch and git push origin +branch

Ty.
  • 3,888
  • 3
  • 24
  • 31

1 Answers1

73

TL;DR

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.

More details

What the git-push man page tells you

The 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 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).

Example

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.

jub0bs
  • 60,866
  • 25
  • 183
  • 186