Question

Github is the default repository for my project (just "origin" renamed to "github"). Something has happened so that "git push" causes a "non-fast-forward updates" error, even though "git push github master" works. "git pull" and "git pull github master" both indicate an up-to-date status. How can I (a) be sure there are no unmerged changes on Github and (b) correct the non-fast-forward error?

$ git status
# On branch master
nothing to commit (working directory clean)
$ git pull
Already up-to-date.
$ git pull github master
From github.com:MikeBlyth/mission_net
 * branch            master     -> FETCH_HEAD
Already up-to-date.
$ git push github master
Everything up-to-date
$ git push
To git@github.com:MikeBlyth/mission_net.git
 ! [rejected]        add_command -> add_command (non-fast-forward)
error: failed to push some refs to 'git@github.com:MikeBlyth/mission_net.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

My git config file is

[core]
  repositoryformatversion = 0
  filemode = true
  bare = false
  logallrefupdates = true
[remote "github"]
  url = git@github.com:MikeBlyth/mission_net.git
  fetch = +refs/heads/*:refs/remotes/github/*
[branch "master"]
  remote = github
  merge = refs/heads/master
[remote "heroku"]
  url = git@heroku.com:joslink.git
  fetch = +refs/heads/*:refs/remotes/heroku/*
  merge = refs/heads/master
[remote "heroku"]
url = git@heroku.com:joslink.git
fetch = +refs/heads/*:refs/remotes/heroku/*
Was it helpful?

Solution

The syntax of 'git push' supports both an explicit and a shorthand version. The explicit version git push github master works for you. The shorthand version git push does not.

If you use the shorthand version you do not tell git what remote to use and what local branch shall be pushed to what remote branch. Hence git has to guess what you mean.

You can configure this with the setup of your remote and the push.default config:

   push.default
       Defines the action git push should take if no refspec is given on
       the command line, no refspec is configured in the remote, and no
       refspec is implied by any of the options given on the command line.
       Possible values are:

       ·    nothing - do not push anything.

       ·    matching - push all matching branches. All branches having the
           same name in both ends are considered to be matching. This is
           the default.

       ·    upstream - push the current branch to its upstream branch.

       ·    tracking - deprecated synonym for upstream.

       ·    current - push the current branch to a branch of the same
           name.

Have a look at git branch -vv to check what branch is tracked by your current branch. Then check git config --get push.default to verify it is doing what you expect.

OTHER TIPS

The explanation could be related to the default refspec used for remote "github":

+refs/heads/*:refs/remotes/github/*

A simple git push would push:

  • to the remote associated to master (here "github"), because master is the current branch (according to the git status)
  • all the other branches (master and add_command branches)

add_command is the one which is not in sync with github remote.

git checkout add_command 
git pull github

Then a git push would work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top