当我使用了一点源代码后,我做了我通常的事情提交,然后推送到远程存储库。但后来我注意到我忘记在源代码中组织导入。因此,我执行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推送原点<分支名称>-f

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

我会怎么做?

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

其他回答

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

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

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将中止。

我也有同样的问题。

意外修改了已推送的最后一个提交在本地做了很多更改,提交了大约五次尝试推送,出现错误,恐慌,合并远程,得到很多不是我的文件,推送,失败等。

作为一个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次),但它节省了一天的工作。

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

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

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

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