在推送非快进提交时git如何失去历史?

时间:2013-11-17 08:58:15

标签: git commit git-push revision-history

我知道有时当我运行git push时,我会收到此错误:

error: failed to push some refs
To prevent you from losing history, non-fast-forward updates were rejected

如果我推送非快进更新,有人会举例说明历史会丢失的情况吗?根据我的理解,当我执行git push时,git只会将我的提交推送到远程存储库而不删除任何现有的提交,那么它将如何丢失历史记录?

谢谢!

2 个答案:

答案 0 :(得分:5)

当您push时,您发送了提交,但您也更新了远程分支。

说远程回购是:

A <- B <- C (master)

现在你克隆它,用commit A开始一些dev,最后得到:

A <- B <- C (origin/master)
  <- D <- E (master)

如果您强制推送,远程仓库将如下所示:

A <- D <- E (master)
  <- B <- C

因此提交B和C仍然存在,但是它们无法通过分支到达。 如果有人现在克隆了回购,他将在当地拥有:

A <- D <- E (master; origin/master)

即:从他的角度来看,提交B和C都会丢失


编辑:

  • “提交仍然存在”意味着:

假设我的提交B有sha1 abcdef。然后,有一个文件objects/ab/cdef(在远程仓库的根目录,在我的本地克隆的.git目录中)代表这个提交。

如果您push -f,它将不会删除此远程文件,因此,提交B仍然存在于远程仓库中。 (至少,只要它不是garbage collected

  • “但是它们无法通过分支到达”暗示:

当我推动其他人克隆此遥控器后,他将获得此.git/objects/ab/cdef文件。但是,除非he is looking for it,否则他一旦存在就不会意识到此提交。例如,gitk --all不会显示它。

答案 1 :(得分:0)

假设您将本地master推送到远程master

如果您的本地分支机构和远程分支机构发生了分歧(两者都有自上次提交以来的提交),那将如何处理?

一种方法是将本地master的当前提交声明为新的远程master。但是这会丢失当前在远程master上提交的历史记录,因为它们永远不会出现在您提交的祖先中。

(我认为“丢失”提交仍然会远程存在,但它们不会在master分支上。)