Git非快进被拒绝

ryn*_*rtn 87 git version-control

我觉得这个问题已被多次询问,但解决方案通常是"我删除了目录并重新完成了我的工作." 我做了提交和推送,但意识到我在提交消息中提到了错误的票号.所以我在SO上寻找快速解决方案并最终在终端中键入以下内容:

$ git reset --soft HEAD^
$ git commit -m "... correct message ..."
Run Code Online (Sandbox Code Playgroud)

唯一的问题是我收到以下错误消息:

To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.
Run Code Online (Sandbox Code Playgroud)

我正在使用git-flow模型,正在开发分支.我怎样才能将东西合并回来让git再次开心?

Bri*_*ell 173

如果按一个提交到服务器,然后重写在本地提交(有git reset,git rebase,git filter-branch,或其他任何历史操作),然后推说改写提交备份到服务器上,你会搞砸了谁比谁已经退出.这是一个例子; 说你已经提交了A,并将其推送到服务器.

-*-*-A <-- master

-*-*-A <-- origin/master

现在你决定以你提到的方式重写A,重置和重新提交.请注意,这会留下一个悬空提交,A,最终将被垃圾收集,因为它无法访问.

-*-*-A
    \
     A' <-- master

-*-*-A  <-- origin/master

如果其他人,让我们说弗雷德,master在你这样做时从服务器上撤下来,他们将会引用A,他们可能会开始工作:

-*-*-A' <-- master

-*-*-A  <-- origin/master

-*-*-A-B <-- fred/master

现在,如果你能够将你的A'推向原点/主人,这将创造一个非快进,那么它的历史就不会有A. 因此,如果弗雷德试图再次拉动,他突然必须合并,并将重新引入A提交:

-*-*-A' <-- master

-*-*-A  <-- origin/master

-*-*-A-B-\ 
    \     * <-- fred/master
     A'--/

如果Fred碰巧注意到了这一点,那么他就可以做一个rebase,这会阻止提交A再次出现.但他必须注意到这一点,并记得这样做; 如果你有多个人将A拉下来,他们都必须重新调整以避免在树中获得额外的A提交.

因此,改变其他人从中撤出的回购的历史通常不是一个好主意.但是,如果您碰巧知道没有其他人从该回购中获取(例如,它是您自己的私人回购,或者您只有另一个开发项目的开发人员可以轻松协调),那么您可以强制通过运行更新:

git push -f
Run Code Online (Sandbox Code Playgroud)

要么

git push origin +master
Run Code Online (Sandbox Code Playgroud)

这些都将忽略对非快进推送的检查,并将服务器上的内容更新为新的A'版本,放弃A版本,以便最终进行垃圾回收.

使用receive.denyNonFastForwardsconfig选项可以完全禁用强制推送.默认情况下,在共享存储库上启用此选项.在这种情况下,如果你真的,真的想强制推送,最好的选择是删除分支并重新创建它git push origin :master; git push origin master:master.但是,denyNonFastForwards启用该选项的原因如上所述; 在共享存储库上,这意味着现在每个使用它的人都需要确保他们重新登录到新历史记录.

在共享存储库中,通常最好只在顶部推送新的提交来解决您遇到的任何问题; 您可以使用git revert生成提交来撤消先前提交的更改.

  • 或者使用不那么神秘的`git push --force` (7认同)
  • @Srikanth使用`receive.denyNonFastForwards`配置选项可以完全禁用强制推送.默认情况下,在共享存储库上启用此选项.在这种情况下,如果你真的,真的想强制推送,最好的选择是删除分支并重新创建它,使用`git push origin:remote_A; git push origin local_A:remote_A`.但是请阅读我上面写的关于为什么在共享存储库上执行此类工作流不好的想法.如果你有一些东西在你试图摆脱或重写的提交中导致严重问题,你应该尝试只做这件事. (4认同)
  • @Panique你试图让几个人同时处理一个庞大而复杂的代码库,而不会相互阻塞(一次只允许一个人处理它),而且不会改变彼此的覆盖.您需要每个人都能够独立进行更改,并合并这些更改.合并(无论是手动还是自动)都会带来意想不到的问题; 所以你想保留尽可能多的信息,以便能够弄清楚如果出错了会发生什么.这本质上是复杂的; 它不脏,只是一个难题. (3认同)

Ala*_*avi 52

力量git push:

git push origin +develop
Run Code Online (Sandbox Code Playgroud)

  • 这是一个解决方案,但请阅读Brian Campbell的评论,以便您在使用之前了解自己在做什么. (24认同)
  • git push origin + master (5认同)

小智 14

你可能需要做一个git pull,可以为你自动合并东西.然后你可以再次提交.如果您有冲突,它会提示您解决它们.

请记住,如果您没有更新gitconfig以指定,则必须指定要从哪个分支中提取...

例如:

git pull origin develop:develop
Run Code Online (Sandbox Code Playgroud)


Ngu*_*inh 7

我正在使用EGit,我也遇到了这个问题.只是尝试rebase了当前的分支,它工作.