如何将修改后的提交推送到远程Git存储库?
当我用我的源代码工作了一下,我做了我平常的事情提交,然后我推到远程存储库。 但后来我注意到我忘了在源代码中组织我的导入。 所以我执行修改命令来取代以前的提交:
> git commit --amend
不幸的是,提交不能被推回到版本库。 这是拒绝的:
> 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/'
我该怎么办? (我可以访问远程存储库。)
实际上我曾经用--force
和.git
仓库推过,被Linus BIG TIME骂了一顿。 总的来说,这会给其他人带来很多问题。 一个简单的答案是“不要这样做”。
无论如何,我看到其他人都这样做,所以我不会在这里重复。 但是,在使用–force(或+ master)推出修改的提交之后,可以从这种情况中恢复。
- find你修改的旧的提交(称之为
old
,我们将通过修改new
调用你创build的新提交)。 - 创build一个
old
和new
的合并,loggingnew
的树,像git checkout new && git merge -s ours old
。 - 用
git merge master
到你的git merge master
- 用
git push . HEAD:master
更新你的主结果git push . HEAD:master
git push . HEAD:master
- 推出结果。
那么,那些不幸地以自己的工作为基础的人,通过修改和强迫推行(这是你是一个非常非常糟糕的男孩 )来消灭你的工作,将会看到由此产生的合并,将会看到你对new
old
赞成。 他们以后的合并不会看到你们修正后造成的old
矛盾,所以他们不必受苦。
您正在看到Git安全function。 Git拒绝用你的分支更新远程分支,因为你的分支的头部提交不是你正在推送的分支的当前头提交的直接后代。
如果情况并非如此,那么同时推送到同一个存储库的两个人不会知道同时发生了一个新的提交,而最后推送的任何人都将失去之前推送者的工作,而没有他们意识到这一点。
如果你知道你是唯一的推送人员,并且你想推送一个修改的提交或推送一个提交分支的提交,你可以'强迫'Git通过使用-f
开关来更新远程分支。
git push -f origin master
即使这可能不起作用,因为Git允许远程存储库通过使用configurationvariablesreceive.denynonfastforwards
拒绝在远端的非快速推送。 如果是这种情况,拒绝原因将如下所示(注意“远程拒绝”部分):
! [remote rejected] master -> master (non-fast forward)
要解决这个问题,你需要改变远程仓库的configuration,或者作为一个肮脏的黑客,你可以删除并重新创build分支:
git push origin :master git push origin master
通常, git push
的最后一个参数使用格式<local_ref>:<remote_ref>
,其中local_ref
是本地存储库上分支的名称, remote_ref
是远程存储库上分支的名称。 这个命令对使用两个shorthands。 :master
有一个null local_ref,这意味着将一个空分支推送到远程master
端,即删除远端分支。 没有的分支名称:
表示将具有给定名称的本地分支推送到具有相同名称的远程分支。 master
在这种情况下是master:master
。
快速咆哮:事实上,没有人在这里发布简单的答案,这表明了Git CLI展示的令人绝望的用户敌意。
无论如何,假设你还没有试图强行推行,那么“明显”的做法就是先拉。 这拉动了你修改的变化(所以不再有),以便你再次拥有它。
一旦你解决了任何冲突,你可以再次推动。
所以:
git pull
如果你在拉取错误,可能是你的本地存储库configuration有问题(我在.git / config分支部分有一个错误的参考)。
之后
git push
也许你会得到一个额外的提交与主题告诉“琐事合并”。
简短的回答:不要将修改后的提交文件推入公共回购。
长答案:一些Git命令,如git commit --amend
和git rebase
,实际上是重写历史图表。 只要你没有发表你的改变,这没什么问题,但是一旦你这样做了,你真的不应该把历史弄糟,因为如果有人已经有了改变,那么当他们再次拉时,可能会失败。 而不是修改一个提交,你应该做一个新的提交与变化。
但是,如果你确实想要推送一个修改的提交,你可以这样做:
$ git push origin +master:master
领先的+
符号会强制推送发生,即使它不会导致“快进”提交。 (当你推动的变化是公共回购已经发生的变化的直接后代时,就会发生快速提交。)
这是一个非常简单和干净的方式来推动你的修改后,你已经做了一个commit --amend
:
git reset --soft HEAD^ git stash git push -f origin master git stash pop git commit git push origin master
哪一个有以下几点:
- 将分支头重置为父提交。
- 隐藏这最后的提交。
- 强制推送到远程。 远程现在没有最后的提交。
- popup你的藏匿处。
- 提交干净。
- 推到远程。
我已经通过放弃我的本地修改的提交并在顶部添加新的更改来解决它:
# 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
我有同样的问题。
- 意外修改了已经推送的最后一个提交
- 在本地做了很多改变,做了五次
- 试图推动,有一个错误,恐慌,远程合并,有很多非我的文件,推,失败等
作为一个Git新手,我认为这是完整的FUBAR 。
解决scheme:有点像@barabuild议+创build一个本地备份分支
# 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
也许这不是一个快速和干净的解决scheme,我失去了我的历史(1承诺,而不是5),但它节省了一天的工作。
这是一个非常简单和干净的方式来推动你的变化后,你已经做了一个git add "your files"
和git commit --amend
:
git push origin master -f
要么:
git push origin master --force
如果您没有将代码推送到远程分支(GitHub / Bitbucket),您可以在命令行上更改提交消息,如下所示。
git commit --amend -m "Your new message"
如果您正在使用特定的分支,请执行以下操作:
git commit --amend -m "BRANCH-NAME: new message"
如果您已经用错误的消息推送了代码,那么在更改消息时需要小心。 即在您更改提交消息并尝试再次推送后,最终会出现问题。 要使其顺利进行,请按照以下步骤操作。
在做之前请阅读完整的答案
git commit --amend -m "BRANCH-NAME : your new message" git push -f origin BRANCH-NAME # Not a best practice. Read below why?
重要说明:当直接使用强制推送时,可能会遇到其他开发人员在同一分支上工作的代码问题。 所以为了避免这些冲突,在进行强制推送之前,需要从分支中提取代码:
git commit --amend -m "BRANCH-NAME : your new message" git pull origin BRANCH-NAME git push -f origin BRANCH-NAME
如果已经推送了,这是更改提交消息时的最佳做法。
如果你知道没有人提交你的未修改的提交,请使用git push
的--force-with-lease
选项。
在TortoiseGit中,您可以在“推送…”选项“强制:可以放弃”并检查“已知更改”下执行同样的操作。
强制(可能丢弃已知的更改)允许远程存储库接受更安全的非快进推送。 这可能会导致远程存储库丢失提交; 小心使用它。 这可以防止丢失遥控器上其他人的未知变化。 它检查服务器分支是否指向与远程跟踪分支相同的提交(已知更改)。 如果是的话,将会执行强制推送。 否则会被拒绝。 由于git没有远程追踪标签,所以使用这个选项不能覆盖标签。
我必须解决这个问题,从远程回购拉和处理合并冲突,出现,提交,然后推。 但是我觉得还有更好的办法。
你得到这个错误,因为Git远程已经有这些提交文件。 你必须强制推动这个分支来工作:
git push -f origin branch_name
另外,请确保您从远程获取代码,因为您团队中的其他人可能已经推送到同一分支。
git pull origin branch_name
这是我们必须强制推送到远程的情况之一。
我只是继续做Git告诉我要做的事情。 所以:
- 由于修改了提交,无法推送。
- 我build议拉一拉。
- 合并失败。 所以我手动修复它。
- 创build一个新的提交(标记为“合并”)并推送它。
- 这似乎工作!
注意:修改的提交是最新的提交。