2014-12-04 106 views
4

状态:学习git。Git重置和强制推送

我做的在两个系统间

系统1

git reset --hard "SHA Key" 
git push origin master # fails 
git push -f origin master # succeeds 

系统下列2

git pull origin master 

我得到这个消息 “已经跟上时代的。”

系统1中更新/重置的任何原因没有反映在系统2中的任何原因?

+0

在系统2上,执行'git fetch',然后在两个系统上比较'git rev-parse origin/master'和'git rev-parse master'。他们都一样吗?两个系统上的 – cmbuckley 2014-12-04 10:22:37

+1

都使用'git branch -vv'来查看跟踪分支设置。这可能是因为在其中之一上,'master'跟踪的是除origin/master之外的其他分支,或者根本不跟踪。 – GolfWolf 2014-12-04 10:27:24

+0

有关跟踪分支的更多详细信息,请访问:http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches#Tracking-Branches – GolfWolf 2014-12-04 10:28:19

回答

5

原因是你可能倒退了主人。

A --- B --- C --- D 

要这样:你从这个去

A --- B --- C 

系统2的​​本地master分支仍像第一张图片,虽然,但从Git的点 ,它包含了所有的历史主产地的 因为当地分行已经包含提交A,B和C

我发现,最好的办法来解释这是有三种观点在 混帐:

1)您当地的分支机构。这些是你通常结账和操作的东西。 2)远程分支机构。这些是远程存储库上的实际分支。 3)你的本地快照的远程分支机构。这些是你在 refs/remotes下找到的。它是您上次将它们拖放到 远程存储库上的分支机构的副本。

当你这样做:

git reset --hard "SHA Key" 

您的影响1),本地主分支。

此:

git push -f origin master 

更新二者2)和3)。我的意思是远程存储库已更新 (refs/heads/master被分配了新的提交)。此外,在本地, refs/remotes/origin/master将被更新以匹配您的推送。

在系统2,本:

git pull origin master 

说任何更新,以获取远程主,并将其应用到本地 分支。作为这个操作的结果,3)也被更新。 refs/remotes/origin/master 现在将指向远程服务器为主分支提供的相同提交。 但是,从Git的角度来看,您已经拥有系统 2的所有本地主分支。你恰好有另一个,D, 下降从A,B和C的历史。换句话说,它现在看起来像是 系统2有一个额外的提交D.Git不会倒带你的分支,并导致你失去这项工作 - 它不明白,你想让它在任何地方都不会变成 。它只在立场下(如数学类型)。你有 的修订,所以你是最新的。顺便说一句,这就是为什么你会看到有关不强制推送 与其他人共享的分支的警告。复卷大师需要团队协调, 和一个足够大的组,它根本不可行。有人不会意识到发生了什么,并且提交会回来。或者,其他人将承诺在 之间导致他们的推送失败,并且他们拉,导致有点愚蠢的看起来 历史,但提交仍然会返回。

如果d导致一个问题,你已经与世界共享,然后 git revert D是一个更好的选择。它不会遇到这些问题,但它确实意味着你现在已经在你的历史中有了逆转。这也意味着 ,D仍然在主设置,这恰好也是一个-D, 撤消它。这有一些其他的含义,但它可能太多而不是 放在这里,而不是直接关系到你的问题。

此外,如果系统1指向系统2,反之亦然,那么我很惊讶Git并没有对你说没有更新远程分支或 工作树。 git push不会更新另一台机器上的工作树,并且 不会让您知道这一点。如果它失败了,那么它可能是一个 错误。

+0

感谢您的详细解释。我得到了大部分。链很长 - A - > B - > C - > ------ R - > S我在系统1中从S重置为C.那么还原[git revert C]解决方案在这里?或者是否在这个前进之前要求球队手动恢复到“C”? – Subramanian 2014-12-04 11:11:02

+0

'git revert C'肯定是你想要的那种情况。 'git reset --hard B'会导致你失去C到S,而且我确信你不需要这个。 :-) – jszakmeister 2014-12-04 11:19:28

0

您将分支的HEAD重置为较早的提交,然后将其作为该(主)分支的头部进行推送。

另一个存储库已经有了旧的提交,所以当你做git pull时,这就是为什么它说已经是最新的 - 它已经提交了。