Git reset –hard and a remote repository

I had a repository that had some bad commits on on it (D, E and F for this example).

A-B-C-D-E-F master and origin/master

  • Git console in Netbeans
  • How to use git stats in Windows 7
  • Ignore files in git log -p
  • How to pull specific directory with git
  • How to isolate Eclipse workspace from git local repository?
  • Can I use a scripted commit template for git?
  • I’ve modified the local repository specifically with a git reset hard. I took a branch before the reset so now I have a repo that looks like:

    A-B-C master  
         \ D-E-F old_master
    A-B-C-D-E-F origin/master

    Now I needed some parts of those bad commits so I cheery picked the bits I needed and made some new commits so now I have the following locally:

    A-B-C-G-H master
         \ D-E-F old_master

    Now I want to push this state of affairs to the remote repo. However, when I try to do a git push git politely gives me the brush off:

    $ git push origin +master:master --force  
    Total 0 (delta 0), reused 0 (delta 0)  
    error: denying non-fast forward refs/heads/master (you should pull first)  
    ! [remote rejected] master -> master (non-fast forward)  
    error: failed to push some refs to ''  

    How do I get the remote repo to take the current state of the local repo?

  • How to cleanup garbage in remote git repo
  • Why is this git clone command failing?
  • Why is my git repository so big?
  • Confirmation of git push command
  • Differences between git fetch and git fetch origin master
  • unable to commit a file, accidentally renamed with mv
  • 4 Solutions collect form web for “Git reset –hard and a remote repository”

    If forcing a push doesn’t help (“git push --force origin” or “git push --force origin master” should be enough), it might mean that the remote server is refusing non fast-forward pushes either via receive.denyNonFastForwards config variable (see git config manpage for description), or via update / pre-receive hook.

    With older Git you can work around that restriction by deleting “git push origin :master” (see the ‘:’ before branch name) and then re-creating “git push origin master” given branch.

    If you can’t change this, then the only solution would be instead of rewriting history to create a commit reverting changes in D-E-F:

    A-B-C-D-E-F-[(D-E-F)^-1]   master
    A-B-C-D-E-F                             origin/master

    To complement Jakub’s answer, if you have access to the remote git server in ssh, you can go into the git remote directory and set:

    user@remote$ git config receive.denyNonFastforwards false

    Then go back to your local repo, try again to do your commit with --force:

    user@local$ git push origin +master:master --force

    And finally revert the server’s setting in the original protected state:

    user@remote$ git config receive.denyNonFastforwards true

    Instead of fixing your “master” branch, it’s way easier to swap it with your “desired-master” by renaming the branches. See This way you wouldn’t even leave any trace of multiple revert logs.

    The whole git resetting business looked far to complicating for me.

    So I did something along the lines to get my src folder in the state i had a few commits ago

    # reset the local state
    git reset <somecommit> --hard 
    # copy the relevant part e.g. src (exclude is only needed if you specify .)
    tar cvfz /tmp/current.tgz --exclude .git  src
    # get the current state of git
    git pull
    # remove what you don't like anymore
    rm -rf src
    # restore from the tar file
    tar xvfz /tmp/current.tgz
    # commit everything back to git
    git commit -a
    # now you can properly push
    git push

    This way the state of affairs in the src is kept in a tar file and git is forced to accept this state without too much fiddling basically the src directory is replaced with the state it had several commits ago.

    Git Baby is a git and github fan, let's start git clone.