如何将修改后的提交推送到远程 Git 存储库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/253055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I push amended commit to the remote Git repository?
提问by Spoike
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.)
我该怎么办?(我可以访问远程存储库。)
采纳答案by Spoike
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".
实际上,我曾经使用--force
和.git
存储库推送并被 Linus BIG TIME骂。一般来说,这会给其他人带来很多问题。一个简单的答案是“不要这样做”。
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 afteryou have pushed out the amended commit with --force (or +master).
反正我看到其他人给出了这样做的秘诀,所以我不会在这里重复。但是这里有一个提示,可以在您使用 --force(或 +master)推出修改后的提交后从这种情况中恢复过来。
- Use
git reflog
to find the old commit that you amended (call itold
, and we'll call the new commit you created by amendingnew
). - Create a merge between
old
andnew
, recording the tree ofnew
, likegit checkout new && git merge -s ours old
. - Merge that to your master with
git merge master
- Update your master with the result with
git push . HEAD:master
- Push the result out.
- 用
git reflog
找旧承诺,你的修正(调用它old
,我们将调用新的承诺创建通过修改new
)。 - 在
old
和之间创建一个合并new
,记录 的树new
,比如git checkout new && git merge -s ours old
。 - 将其合并到您的主人
git merge 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 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.
那么谁是不幸的足够多的人在提交你抹杀通过修改,并迫使一推就会看到最后的合并结果会看到你的青睐已经根据他们的工作new
了old
。他们以后的合并将不会看到您的修改导致的old
和之间的冲突new
,因此他们不必受苦。
回答by CB Bailey
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.
您看到的是 Git 安全功能。Git 拒绝用你的分支更新远程分支,因为你的分支的头部提交不是你正在推送到的分支的当前头部提交的直接后代。
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.
如果你知道你是唯一一个推送的人,并且你想推送一个修改后的提交或推送一个回绕分支的提交,你可以使用-f
开关“强制”Git 更新远程分支。
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):
甚至这也可能不起作用,因为 Git 允许远程存储库通过使用配置变量来拒绝远端的非快进推送receive.denynonfastforwards
。如果是这种情况,拒绝原因将如下所示(注意“远程拒绝”部分):
! [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
.
通常,最后一个参数git push
使用格式<local_ref>:<remote_ref>
,其中local_ref
是本地存储库remote_ref
上的分支名称,是远程存储库上的分支名称。此命令对使用两个简写。:master
有一个 null local_ref 这意味着将一个 null 分支推送到远程端master
,即删除远程分支。一个分支名称没有:
手段将具有给定名称的本地分支推送到具有相同名称的远程分支。master
在这种情况下是 的简称master:master
。
回答by CB Bailey
Quick rant: The fact that no one has posted the simple answer here demonstrates the desperate user-hostility exhibited by the Git CLI.
快速咆哮:没有人在这里发布简单的答案这一事实表明 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).
如果在 pull 中出现错误,可能是本地存储库配置有问题(我在 .git/config 分支部分有错误的引用)。
And after
之后
git push
Maybe you will get an extra commit with the subject telling about a "Trivial merge".
也许你会得到一个关于“琐碎合并”的主题的额外提交。
回答by mipadi
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.
长答案:一些 Git 命令,比如git commit --amend
and git rebase
,实际上重写了历史图。只要你还没有发布你的更改就可以了,但是一旦你发布了,你真的不应该在历史上乱搞,因为如果有人已经拿到了你的更改,那么当他们再次尝试拉取时,它可能会失败. 而不是修改提交,您应该使用更改进行新的提交。
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 descendantof the changes already in the public repo.)
前导+
符号将强制推送发生,即使它不会导致“快进”提交。(当您推送的更改是公共存储库中已有更改的直接后代时,会发生快进提交。)
回答by Faiza
Here is a very simple and clean way to push your changes after you have already made a commit --amend
:
这是一种非常简单和干净的方法,可以在您已经完成更改后推送您的更改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:
执行以下操作:
- Reset branch head to parent commit.
- Stash this last commit.
- Force push to remote. The remote now doesn't have the last commit.
- Pop your stash.
- Commit cleanly.
- Push to remote.
- 将分支头重置为父提交。
- 存储最后一次提交。
- 强制推送到远程。遥控器现在没有最后一次提交。
- 弹出你的藏品。
- 干干净净地答应。
- 推到远程。
Remember to change "origin" and "master" if applying this to a different branch or remote.
如果将其应用于不同的分支或远程,请记住更改“origin”和“master”。
回答by bara
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
回答by davisca
I had the same problem.
我有同样的问题。
- Accidentally amended the last commit that was already pushed
- Done a lot of changes locally, committed some five times
- Tried to push, got an error, panicked, merged remote, got a lot of not-my-files, pushed, failed, etc.
- 不小心修改了已经推送的最后一次提交
- 在本地做了很多改变,提交了大约五次
- 尝试推送,出现错误,恐慌,合并远程,收到很多非我的文件,推送,失败等。
As a Git-newbie, I thought it was complete FUBAR.
作为一个 Git 新手,我认为它是完整的FUBAR。
Solution: Somewhat like @bara suggested + created a local backup branch
解决方案:有点像@bara 建议+创建一个本地备份分支
# 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.
也许这不是一个快速而干净的解决方案,而且我丢失了我的历史记录(1 次提交而不是 5 次),但它节省了一天的工作。
回答by Prabhakar Undurthi
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.
如果您尚未将代码推送到远程分支 (GitHub/Bitbucket),您可以在命令行上更改提交消息,如下所示。
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.
如果已经推送,这是更改提交消息时的最佳实践。
回答by ShawnFeatherly
If you know nobody has pulled your un-amended commit, use the --force-with-lease
option of git push
.
如果你知道,没有人拉你的未修正的提交,使用--force-with-lease
的选项git push
。
In TortoiseGit, you can do the same thing under "Push..." options "Force: May discard" and checking "known changes".
在 TortoiseGit 中,您可以在“推送...”选项“强制:可能丢弃”并检查“已知更改”下执行相同的操作。
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.
强制(可能会丢弃已知更改)允许远程存储库接受更安全的非快进推送。这可能会导致远程存储库丢失提交;小心使用它。这可以防止丢失远程其他人的未知更改。它检查服务器分支是否指向与远程跟踪分支相同的提交(已知更改)。如果是,将执行强制推送。否则会被拒绝。由于 git 没有远程跟踪标签,因此无法使用此选项覆盖标签。
回答by Praveen Dhawan
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 远程已具有这些提交文件。您必须强制推动分支才能使其工作:
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.
这是我们必须强制将提交推送到远程的情况之一。