当我使用了一点源代码后,我做了我通常的事情提交,然后推送到远程存储库。但后来我注意到我忘记在源代码中组织导入。因此,我执行modify命令以替换先前的commit:

> 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/'

我该怎么办?(我可以访问远程存储库。)


我必须通过从远程回购中提取来解决这个问题,并处理出现的合并冲突,提交然后推送。但我觉得还有更好的方法。


简言之:不要将修改后的承诺推至公开回购。

长篇大论:一些Git命令,比如gitcommit--modify和gitrebase,实际上重写了历史图。只要你还没有发布你的更改,这是很好的,但一旦你发布了,你就真的不应该玩弄历史,因为如果有人已经得到了你的更改的话,那么当他们再次尝试时,可能会失败。您不应该修改提交,而应该使用更改进行新的提交。

但是,如果您真的、真的想推动修改的提交,可以这样做:

$ git push origin +master:master

前导+符号将迫使推送发生,即使它不会导致“快进”提交。(当您推送的更改是公共回购中已存在更改的直接后代时,会发生快速提交。)


您正在看到Git安全功能。Git拒绝用您的分支更新远程分支,因为您的分支的头部提交不是您要推送的分支的当前头部提交的直接后代。

如果不是这样的话,那么两个同时推到同一个存储库的人就不会知道同时有一个新的提交,而最后推的人都会失去前一个推的人的工作,而他们中的任何一个都没有意识到这一点。

如果你知道你是唯一一个推送的人,并且你想推送一个修改后的提交或推送一条返回分支的提交,你可以使用-f开关“强制”Git更新远程分支。

git push -f origin master

即使这样也可能不起作用,因为Git允许远程存储库通过使用配置变量receive.denynonfastforwards在远端拒绝非fastforward推送。如果是这种情况,拒绝原因如下(注意“远程拒绝”部分):

 ! [remote rejected] master -> master (non-fast forward)

为了解决这个问题,您需要更改远程存储库的配置,或者作为一个肮脏的黑客,您可以删除并重新创建分支,从而:

git push origin :master
git push origin master

通常,git push的最后一个参数使用格式<local_ref>:<remote_ref>,其中local_ref是本地存储库上分支的名称,remote_ref是远程存储库上的分支的名称。此命令对使用两个短手。:master有一个空的localref,这意味着将一个空分支推送到远程端master,即删除远程分支。没有:的分支名称表示将具有给定名称的本地分支推送到具有相同名称的远程分支。在这种情况下,master是master:master的缩写。


事实上,我曾经用武力和.git存储库推过一次,结果被Linus BIG TIME骂了一顿。一般来说,这会给其他人带来很多问题。一个简单的答案是“不要这样做”。

我看到其他人给出了这样做的方法,所以我在这里不再重复。但这里有一个提示,在您使用--force(或+master)推出修改后的提交后,可以从这种情况中恢复过来。

使用gitreflog查找您修改的旧提交(称之为旧提交,我们将调用您通过修改新提交创建的新提交)。在新旧之间创建一个合并,记录新的树,比如git checkout new&&git merge-s our old。使用gitmergemaster将其合并到您的master用git push更新你的主人。头部:主将结果推出来。

然后,那些不幸地将他们的工作建立在你通过修改和强制推动而消除的承诺之上的人将看到由此产生的合并,他们将看到你喜欢新的而不是旧的。他们后来的合并将不会看到由于您的修改而导致的新旧冲突,因此他们不必遭受损失。


快速咆哮:没有人在这里发布简单的答案,这表明了Git CLI显示出的绝望的用户敌意。

无论如何,如果你没有试图强行推动,那么“显而易见”的方法就是先拉动。这将拉动您修改的更改(因此不再具有),以便您再次拥有它。

一旦解决了任何冲突,就可以再次推送。

So:

git pull

如果在pull中出现错误,可能是本地存储库配置有问题(我在.git/config分支部分中有一个错误的ref)。

之后

git push

也许你会得到一个额外的承诺,主题讲述一个“琐碎的合并”。


我通过放弃本地修改的提交并在顶部添加新的更改来解决这个问题:

# 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。

解决方案:@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

也许这不是一个快速而干净的解决方案,我失去了我的历史(1次提交而不是5次),但它节省了一天的工作。


如果您还没有将代码推送到远程分支(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 reset --soft HEAD^
git stash
git push -f origin master
git stash pop
git commit -a
git push origin master

它执行以下操作:

将分支头重置为父提交。停止这最后的承诺。强制推至远程。远程现在没有最后一次提交。打开你的储藏室。干净地提交。按下遥控器。

如果将此应用于其他分支或远程,请记住更改原点和主控点。


下面是一个非常简单和干净的方法,在您已经进行了git添加“您的文件”和git提交后推送您的更改--修改:

git push origin master -f

or:

git push origin master --force

您收到此错误,因为Git远程已经有这些提交文件。您必须强制推动分支才能使其工作:

git push -f origin branch_name

还要确保您从远程获取代码,因为团队中的其他人可能已经将代码推到了同一分支。

git pull origin branch_name

这是我们必须强制将提交推到远程的情况之一。


如果您知道没有人撤回您未修改的承诺,请使用gitpush的--forcewithlease选项。

在TortoiseGit中,您可以在“推送…”选项“强制:可能丢弃”和检查“已知更改”下执行相同的操作。

强制(可能放弃已知的更改)允许远程存储库接受更安全的非快进推送。这可能会导致远程存储库丢失提交;小心使用。这可以防止丢失来自远程用户的未知更改。它检查服务器分支是否指向与远程跟踪分支相同的提交(已知更改)。如果是,将执行强制推压。否则将被拒绝。由于git没有远程跟踪标记,因此无法使用此选项覆盖标记。


我一直在做Git让我做的事。所以:

无法推送,因为修改了提交。我按照建议拉了一下。合并失败。所以我手动修复。创建新提交(标记为“merge”)并将其推送。它似乎起作用了!

注:修改后的承诺是最新的承诺。


在这里,我如何修复以前提交中的编辑:

保存您的工作到目前为止。如果做了更改,现在就暂时保存:git Stash现在您的工作副本在上次提交时是干净的。进行编辑和修复。在“修改”模式下提交更改:gitcommit--all--modify您的编辑器将显示一条日志消息(默认情况下,是旧的日志消息)。保存并在满意时退出编辑器。新的更改将添加到旧的提交中。使用git log和git diff HEAD自行查看^重新应用隐藏的更改(如果有):git stash apply


在更改提交的作者和提交人时,以下内容对我有效。

git push-f原始主机

Git非常聪明,能够发现这些都是相同delta的提交,只是在元信息部分有所不同。

本地和远程负责人都指出了有问题的提交。


如果您使用的是Visual Studio代码,可以尝试此扩展以使其更容易。

https://marketplace.visualstudio.com/items?itemName=cimdalli.git-提交修改推力

正如您从其名称中可以理解的,它连续执行命令

gitcommit—修改git push—力


为了避免强制推送,在远程裸存储库中,使用以下命令删除最后一次提交(要修改的提交):

git update-ref HEAD HEAD^

然后在没有冲突的情况下推送修改后的提交。

注意:这假设在此期间没有人做出错误的承诺。如果有,他们将不得不同样地倒带并再次拉动,可能会合并自己的更改。


如果要更改的消息是针对存储库的最新提交,则将执行以下命令:

git commit --amend -m "New message"

git push --force repository-name branch-name

注意:除非您确信在最近一次提交后没有其他人克隆过您的存储库,否则不建议使用--force。

更安全的选择是使用:

git push --force-with-lease repository-name branch-name

与-force不同,-force将销毁其他人推送到分支的任何更改,如果存储库有上游更改,-forcewithlease将中止。


您可以通过以下操作以简单、安全的方式进行操作:

使用gitcommit修改您的上一次提交--修改和需要添加的任何选项git pull将本地回购与远程回购同步。拉动后,您将在本地和远程之间发生冲突。您只需接受当前更改并再次提交即可解决这些问题。数字推送

现在,本地和远程回购已更新,无需更改回购历史记录。


在这种情况下,你应该——用力。

基于:

如果是单个项目,我会这样做:git推送原点<分支名称>-f

如果您正在与您的团队合作,或其他同行正在审查和使用您的代码,则不建议使用强制标志。主要是因为你总是想要一个干净的git历史。

我会怎么做?

如果有更多的人在同一个分支机构工作,或者其他人在审查你的代码,我会gitcommit--modify,然后gitpush-f。。。并让人们知道他们需要获取pull-rebase,以便能够看到您的更改。如果在审查PR或MR时发生类似的情况,请添加新的干净提交,并在结尾处清除历史。