Search code examples
gitgit-push

Difference between specifying refspec with git push --tags or not


I stumbled upon this rather obscure problem pushing tags to a remote using the two commands git push --tags and git push --tags origin master. They are not behaving the same in the following situation:

Initial situation

I am trying to push a newly created tag (git tag test) to a remote repo that is one commit ahead because somebody else pushed a commit to it and I did not pull the latest changes. As graphic:

Remote [master] (one commit ahead):
A ----- B ----- C ---- D
Local  [master] (one commit behind):
A ----- B ----- C 
            (tag:test)

Problem

git push --tags is working as expected:

Total 0 (delta 0), reused 0 (delta 0)
To https://remote.gitrepo.com/path/to/project
 * [new tag]         test14 -> test14

git push --tags origin master gets rejected and errors:

Total 0 (delta 0), reused 0 (delta 0)
To https://remote.gitrepo.com/path/to/project
  * [new tag]         test15 -> test15
  ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://remote.gitrepo.com/path/to/project'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Question

Why is git push --tags origin master trying to push something apart from the tag? I am asking why the command is trying to push the branch to the remote and not why it is being rejected


Solution

  • I am asking why the command is trying to push the branch to the remote and not why it is being rejected,

    Because git push will push new commits and (with --tags) new tags.

    • C is already pushed so nothing to push there
    • the new tag is pushed.

    In your second case, you are trying to reset the remote master branch (which is at D) to C (in addition of pushing tags).