When I've worked a bit with my source code, I did my usual thing commit and then I pushed to a remote repository. But then I noticed I forgot to organize my imports in the source code. So I do the amend command to replace the previous commit:
> git commit --amend
Unfortunately the commit can't be pushed back to the repository. It is rejected like this:
> git push origin
To //my.remote.repo.com/stuff.git/
! [rejected] master -> master (non-fast forward)
error: failed to push some refs to '//my.remote.repo.com/stuff.git/'
What should I do? (I can access the remote repository.)
This question is related to
git
git-commit
git-amend
You are seeing a Git safety feature. Git refuses to update the remote branch with your branch, because your branch's head commit is not a direct descendent of the current head commit of the branch that you are pushing to.
If this were not the case, then two people pushing to the same repository at about the same time would not know that there was a new commit coming in at the same time and whoever pushed last would lose the work of the previous pusher without either of them realising this.
If you know that you are the only person pushing and you want to push an amended commit or push a commit that winds back the branch, you can 'force' Git to update the remote branch by using the -f
switch.
git push -f origin master
Even this may not work as Git allows remote repositories to refuse non-fastforward pushes at the far end by using the configuration variable receive.denynonfastforwards
. If this is the case the rejection reason will look like this (note the 'remote rejected' part):
! [remote rejected] master -> master (non-fast forward)
To get around this, you either need to change the remote repository's configuration or as a dirty hack you can delete and recreate the branch thus:
git push origin :master
git push origin master
In general the last parameter to git push
uses the format <local_ref>:<remote_ref>
, where local_ref
is the name of the branch on the local repository and remote_ref
is the name of the branch on the remote repository. This command pair uses two shorthands. :master
has a null local_ref which means push a null branch to the remote side master
, i.e. delete the remote branch. A branch name with no :
means push the local branch with the given name to the remote branch with the same name. master
in this situation is short for master:master
.
I had to fix this problem with pulling from the remote repo and deal with the merge conflicts that arose, commit and then push. But I feel like there is a better way.
If you know nobody has pulled your un-amended commit, use the --force-with-lease
option of git push
.
In TortoiseGit, you can do the same thing under "Push..." options "Force: May discard" and checking "known changes".
Force (May discard known changes) allows the remote repository to accept a safer non-fast-forward push. This can cause the remote repository to lose commits; use it with care. This can prevent from losing unknown changes from other people on the remote. It checks if the server branch points to the same commit as the remote-tracking branch (known changes). If yes, a force push will be performed. Otherwise it will be rejected. Since git does not have remote-tracking tags, tags cannot be overwritten using this option.
Here is a very simple and clean way to push your changes after you have already made a git add "your files"
and git commit --amend
:
git push origin master -f
or:
git push origin master --force
I just kept doing what Git told me to do. So:
Note: The amended commit was the latest one.
I had to fix this problem with pulling from the remote repo and deal with the merge conflicts that arose, commit and then push. But I feel like there is a better way.
Here is a very simple and clean way to push your changes after you have already made a commit --amend
:
git reset --soft HEAD^
git stash
git push -f origin master
git stash pop
git commit -a
git push origin master
Which does the following:
Remember to change "origin" and "master" if applying this to a different branch or remote.
Short answer: Don't push amended commits to a public repo.
Long answer: A few Git commands, like git commit --amend
and git rebase
, actually rewrite the history graph. This is fine as long as you haven't published your changes, but once you do, you really shouldn't be mucking around with the history, because if someone already got your changes, then when they try to pull again, it might fail. Instead of amending a commit, you should just make a new commit with the changes.
However, if you really, really want to push an amended commit, you can do so like this:
$ git push origin +master:master
The leading +
sign will force the push to occur, even if it doesn't result in a "fast-forward" commit. (A fast-forward commit occurs when the changes you are pushing are a direct descendant of the changes already in the public repo.)
I have solved it by discarding my local amended commit and adding the new changes on top:
# Rewind to commit before conflicting
git reset --soft HEAD~1
# Pull the remote version
git pull
# Add the new commit on top
git add ...
git commit
git push
If you are using Visual Studio Code, you can try this extension to make it easier.
https://marketplace.visualstudio.com/items?itemName=cimdalli.git-commit-amend-push-force
As you can understand from its name, it executes commands consecutively
git commit --amend
git push --force
I had to fix this problem with pulling from the remote repo and deal with the merge conflicts that arose, commit and then push. But I feel like there is a better way.
I had the same problem.
As a Git-newbie, I thought it was complete FUBAR.
Solution: Somewhat like @bara suggested + created a local backup branch
# Rewind to commit just before the pushed-and-amended one.
# Replace <hash> with the needed hash.
# --soft means: leave all the changes there, so nothing is lost.
git reset --soft <hash>
# Create new branch, just for a backup, still having all changes in it.
# The branch was feature/1234, new one - feature/1234-gone-bad
git checkout -b feature/1234-gone-bad
# Commit all the changes (all the mess) not to lose it & not to carry around
git commit -a -m "feature/1234 backup"
# Switch back to the original branch
git checkout feature/1234
# Pull the from remote (named 'origin'), thus 'repairing' our main problem
git pull origin/feature/1234
# Now you have a clean-and-non-diverged branch and a backup of the local changes.
# Check the needed files from the backup branch
git checkout feature/1234-gone-bad -- the/path/to/file.php
Maybe it's not a fast and clean solution, and I lost my history (1 commit instead of 5), but it saved a day's work.
I had the same problem.
As a Git-newbie, I thought it was complete FUBAR.
Solution: Somewhat like @bara suggested + created a local backup branch
# Rewind to commit just before the pushed-and-amended one.
# Replace <hash> with the needed hash.
# --soft means: leave all the changes there, so nothing is lost.
git reset --soft <hash>
# Create new branch, just for a backup, still having all changes in it.
# The branch was feature/1234, new one - feature/1234-gone-bad
git checkout -b feature/1234-gone-bad
# Commit all the changes (all the mess) not to lose it & not to carry around
git commit -a -m "feature/1234 backup"
# Switch back to the original branch
git checkout feature/1234
# Pull the from remote (named 'origin'), thus 'repairing' our main problem
git pull origin/feature/1234
# Now you have a clean-and-non-diverged branch and a backup of the local changes.
# Check the needed files from the backup branch
git checkout feature/1234-gone-bad -- the/path/to/file.php
Maybe it's not a fast and clean solution, and I lost my history (1 commit instead of 5), but it saved a day's work.
You are seeing a Git safety feature. Git refuses to update the remote branch with your branch, because your branch's head commit is not a direct descendent of the current head commit of the branch that you are pushing to.
If this were not the case, then two people pushing to the same repository at about the same time would not know that there was a new commit coming in at the same time and whoever pushed last would lose the work of the previous pusher without either of them realising this.
If you know that you are the only person pushing and you want to push an amended commit or push a commit that winds back the branch, you can 'force' Git to update the remote branch by using the -f
switch.
git push -f origin master
Even this may not work as Git allows remote repositories to refuse non-fastforward pushes at the far end by using the configuration variable receive.denynonfastforwards
. If this is the case the rejection reason will look like this (note the 'remote rejected' part):
! [remote rejected] master -> master (non-fast forward)
To get around this, you either need to change the remote repository's configuration or as a dirty hack you can delete and recreate the branch thus:
git push origin :master
git push origin master
In general the last parameter to git push
uses the format <local_ref>:<remote_ref>
, where local_ref
is the name of the branch on the local repository and remote_ref
is the name of the branch on the remote repository. This command pair uses two shorthands. :master
has a null local_ref which means push a null branch to the remote side master
, i.e. delete the remote branch. A branch name with no :
means push the local branch with the given name to the remote branch with the same name. master
in this situation is short for master:master
.
Short answer: Don't push amended commits to a public repo.
Long answer: A few Git commands, like git commit --amend
and git rebase
, actually rewrite the history graph. This is fine as long as you haven't published your changes, but once you do, you really shouldn't be mucking around with the history, because if someone already got your changes, then when they try to pull again, it might fail. Instead of amending a commit, you should just make a new commit with the changes.
However, if you really, really want to push an amended commit, you can do so like this:
$ git push origin +master:master
The leading +
sign will force the push to occur, even if it doesn't result in a "fast-forward" commit. (A fast-forward commit occurs when the changes you are pushing are a direct descendant of the changes already in the public repo.)
I had to fix this problem with pulling from the remote repo and deal with the merge conflicts that arose, commit and then push. But I feel like there is a better way.
If you have not pushed the code to your remote branch (GitHub/Bitbucket) you can change the commit message on the command line as below.
git commit --amend -m "Your new message"
If you're working on a specific branch, do this:
git commit --amend -m "BRANCH-NAME: new message"
If you've already pushed the code with a wrong message then you need to be careful when changing the message. i.e after you change the commit message and try pushing it again you end up with having issues. To make it smooth follow the following steps.
Please read the entire answer before doing it
git commit --amend -m "BRANCH-NAME : your new message"
git push -f origin BRANCH-NAME # Not a best practice. Read below why?
Important note: When you use the force push directly you might end up with code issues that other developers are working on the same branch. So to avoid those conflicts you need to pull the code from your branch before making the force push:
git commit --amend -m "BRANCH-NAME : your new message"
git pull origin BRANCH-NAME
git push -f origin BRANCH-NAME
This is the best practice when changing the commit message, if it was already pushed.
Quick rant: The fact that no one has posted the simple answer here demonstrates the desperate user-hostility exhibited by the Git CLI.
Anyway, the "obvious" way to do this, assuming you haven't tried to force the push, is to pull first. This pulls the change that you amended (and so no longer have) so that you have it again.
Once you have resolved any conflicts, you can push again.
So:
git pull
If you get errors in pull, maybe something is wrong in your local repository configuration (I had a wrong ref in the .git/config branch section).
And after
git push
Maybe you will get an extra commit with the subject telling about a "Trivial merge".
Here, How I fixed an edit in a previous commit:
Save your work so far.
Stash your changes away for now if made: git stash
Now your working copy is clean at the state of your last commit.
Make the edits and fixes.
Commit the changes in "amend" mode: git commit --all --amend
Your editor will come up asking for a log message (by default, the old log message). Save and quit the editor when you're happy with it.
The new changes are added on to the old commit. See for yourself with git log
and git diff HEAD^
Re-apply your stashed changes, if made: git stash apply
If you have not pushed the code to your remote branch (GitHub/Bitbucket) you can change the commit message on the command line as below.
git commit --amend -m "Your new message"
If you're working on a specific branch, do this:
git commit --amend -m "BRANCH-NAME: new message"
If you've already pushed the code with a wrong message then you need to be careful when changing the message. i.e after you change the commit message and try pushing it again you end up with having issues. To make it smooth follow the following steps.
Please read the entire answer before doing it
git commit --amend -m "BRANCH-NAME : your new message"
git push -f origin BRANCH-NAME # Not a best practice. Read below why?
Important note: When you use the force push directly you might end up with code issues that other developers are working on the same branch. So to avoid those conflicts you need to pull the code from your branch before making the force push:
git commit --amend -m "BRANCH-NAME : your new message"
git pull origin BRANCH-NAME
git push -f origin BRANCH-NAME
This is the best practice when changing the commit message, if it was already pushed.
You are seeing a Git safety feature. Git refuses to update the remote branch with your branch, because your branch's head commit is not a direct descendent of the current head commit of the branch that you are pushing to.
If this were not the case, then two people pushing to the same repository at about the same time would not know that there was a new commit coming in at the same time and whoever pushed last would lose the work of the previous pusher without either of them realising this.
If you know that you are the only person pushing and you want to push an amended commit or push a commit that winds back the branch, you can 'force' Git to update the remote branch by using the -f
switch.
git push -f origin master
Even this may not work as Git allows remote repositories to refuse non-fastforward pushes at the far end by using the configuration variable receive.denynonfastforwards
. If this is the case the rejection reason will look like this (note the 'remote rejected' part):
! [remote rejected] master -> master (non-fast forward)
To get around this, you either need to change the remote repository's configuration or as a dirty hack you can delete and recreate the branch thus:
git push origin :master
git push origin master
In general the last parameter to git push
uses the format <local_ref>:<remote_ref>
, where local_ref
is the name of the branch on the local repository and remote_ref
is the name of the branch on the remote repository. This command pair uses two shorthands. :master
has a null local_ref which means push a null branch to the remote side master
, i.e. delete the remote branch. A branch name with no :
means push the local branch with the given name to the remote branch with the same name. master
in this situation is short for master:master
.
Short answer: Don't push amended commits to a public repo.
Long answer: A few Git commands, like git commit --amend
and git rebase
, actually rewrite the history graph. This is fine as long as you haven't published your changes, but once you do, you really shouldn't be mucking around with the history, because if someone already got your changes, then when they try to pull again, it might fail. Instead of amending a commit, you should just make a new commit with the changes.
However, if you really, really want to push an amended commit, you can do so like this:
$ git push origin +master:master
The leading +
sign will force the push to occur, even if it doesn't result in a "fast-forward" commit. (A fast-forward commit occurs when the changes you are pushing are a direct descendant of the changes already in the public repo.)
The following worked for me when changing Author and Committer of a commit.
git push -f origin master
Git was smart enough to figure out that these were commits of identical deltas which only differed in the meta information section.
Both the local and remote heads pointed to the commits in question.
Short answer: Don't push amended commits to a public repo.
Long answer: A few Git commands, like git commit --amend
and git rebase
, actually rewrite the history graph. This is fine as long as you haven't published your changes, but once you do, you really shouldn't be mucking around with the history, because if someone already got your changes, then when they try to pull again, it might fail. Instead of amending a commit, you should just make a new commit with the changes.
However, if you really, really want to push an amended commit, you can do so like this:
$ git push origin +master:master
The leading +
sign will force the push to occur, even if it doesn't result in a "fast-forward" commit. (A fast-forward commit occurs when the changes you are pushing are a direct descendant of the changes already in the public repo.)
You are getting this error because the Git remote already has these commit files. You have to force push the branch for this to work:
git push -f origin branch_name
Also make sure you pull the code from remote as someone else on your team might have pushed to the same branch.
git pull origin branch_name
This is one of the cases where we have to force push the commit to remote.
Here is a very simple and clean way to push your changes after you have already made a git add "your files"
and git commit --amend
:
git push origin master -f
or:
git push origin master --force
If you know nobody has pulled your un-amended commit, use the --force-with-lease
option of git push
.
In TortoiseGit, you can do the same thing under "Push..." options "Force: May discard" and checking "known changes".
Force (May discard known changes) allows the remote repository to accept a safer non-fast-forward push. This can cause the remote repository to lose commits; use it with care. This can prevent from losing unknown changes from other people on the remote. It checks if the server branch points to the same commit as the remote-tracking branch (known changes). If yes, a force push will be performed. Otherwise it will be rejected. Since git does not have remote-tracking tags, tags cannot be overwritten using this option.
The following worked for me when changing Author and Committer of a commit.
git push -f origin master
Git was smart enough to figure out that these were commits of identical deltas which only differed in the meta information section.
Both the local and remote heads pointed to the commits in question.
Quick rant: The fact that no one has posted the simple answer here demonstrates the desperate user-hostility exhibited by the Git CLI.
Anyway, the "obvious" way to do this, assuming you haven't tried to force the push, is to pull first. This pulls the change that you amended (and so no longer have) so that you have it again.
Once you have resolved any conflicts, you can push again.
So:
git pull
If you get errors in pull, maybe something is wrong in your local repository configuration (I had a wrong ref in the .git/config branch section).
And after
git push
Maybe you will get an extra commit with the subject telling about a "Trivial merge".
I just kept doing what Git told me to do. So:
Note: The amended commit was the latest one.
You are getting this error because the Git remote already has these commit files. You have to force push the branch for this to work:
git push -f origin branch_name
Also make sure you pull the code from remote as someone else on your team might have pushed to the same branch.
git pull origin branch_name
This is one of the cases where we have to force push the commit to remote.
If you are using Visual Studio Code, you can try this extension to make it easier.
https://marketplace.visualstudio.com/items?itemName=cimdalli.git-commit-amend-push-force
As you can understand from its name, it executes commands consecutively
git commit --amend
git push --force
I have solved it by discarding my local amended commit and adding the new changes on top:
# Rewind to commit before conflicting
git reset --soft HEAD~1
# Pull the remote version
git pull
# Add the new commit on top
git add ...
git commit
git push
Here, How I fixed an edit in a previous commit:
Save your work so far.
Stash your changes away for now if made: git stash
Now your working copy is clean at the state of your last commit.
Make the edits and fixes.
Commit the changes in "amend" mode: git commit --all --amend
Your editor will come up asking for a log message (by default, the old log message). Save and quit the editor when you're happy with it.
The new changes are added on to the old commit. See for yourself with git log
and git diff HEAD^
Re-apply your stashed changes, if made: git stash apply
You are seeing a Git safety feature. Git refuses to update the remote branch with your branch, because your branch's head commit is not a direct descendent of the current head commit of the branch that you are pushing to.
If this were not the case, then two people pushing to the same repository at about the same time would not know that there was a new commit coming in at the same time and whoever pushed last would lose the work of the previous pusher without either of them realising this.
If you know that you are the only person pushing and you want to push an amended commit or push a commit that winds back the branch, you can 'force' Git to update the remote branch by using the -f
switch.
git push -f origin master
Even this may not work as Git allows remote repositories to refuse non-fastforward pushes at the far end by using the configuration variable receive.denynonfastforwards
. If this is the case the rejection reason will look like this (note the 'remote rejected' part):
! [remote rejected] master -> master (non-fast forward)
To get around this, you either need to change the remote repository's configuration or as a dirty hack you can delete and recreate the branch thus:
git push origin :master
git push origin master
In general the last parameter to git push
uses the format <local_ref>:<remote_ref>
, where local_ref
is the name of the branch on the local repository and remote_ref
is the name of the branch on the remote repository. This command pair uses two shorthands. :master
has a null local_ref which means push a null branch to the remote side master
, i.e. delete the remote branch. A branch name with no :
means push the local branch with the given name to the remote branch with the same name. master
in this situation is short for master:master
.
Source: Stackoverflow.com