How do I push amended commit to the remote Git repository?
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.)
I actually once pushed with --force
and .git
repository and got scolded by Linus BIG TIME . In general this will create a lot of problems for other people. A simple answer is "Don't do it".
I see others gave the recipe for doing so anyway, so I won't repeat them here. But here is a tip to recover from the situation after you have pushed out the amended commit with --force (or +master).
old
, and we'll call the new commit you created by amending new
). old
and new
, recording the tree of new
, like git checkout new && git merge -s ours old
. git merge master
git push . HEAD:master
git push . HEAD:master
Then people who were unfortunate enough to have based their work on the commit you obliterated by amending and forcing a push (which is you're being a very very bad boy ) will see the resulting merge will see that you favor new
over old
. Their later merges will not see the conflicts between old
and new
that resulted from your amending, so they do not have to suffer.
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
, ie 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
.
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".
链接地址: http://www.djcxy.com/p/1346.html上一篇: Git工作流和rebase vs合并问题