0

情况

  • 我有一个本地 Git 存储库。

在此处输入图像描述

  • 我只有在分支上: master

  • 我曾经有另一个分支,但我将它合并到master然后删除它。

  • 这种合并和删除的分支从fe6263e.

  • 0c81926是一个--修正c79dc19

  • 没有标签,也没有任何其他指向c79dc19. 我知道,如果某个对象指向修改后的提交,则此类提交将继续显示在历史记录中。但这种情况并非如此。

问题

  • 为什么历史线没有变平?

  • 为什么还在c79dc19显示?

  • 这是怎么发生的?

正如我所提到的,没有任何意义,我做了一个git -gc清理任何挂起的提交。

4

3 回答 3

2

您从 master 创建了新分支,c79因此 master 继续指向那里。然后从新分支提交修改,因此主分支和新分支的历史不同。

需要注意的一件事是,修改实际上并没有修改提交。提交是不可变的。一个修改基于另一个创建一个新的提交。

如果要展平它,则将 master 指向上一个提交并合并到提示。

git checkout -b temp
git branch -f master fe6263e
git checkout master
git merge f6429eb
于 2016-11-09T18:35:48.520 回答
2

没有标签或任何其他 [commit] 指向c79dc19

这不是历史所显示的。

尝试运行git show HEAD- 它会显示合并的两个父项是什么。从您的图表中看,它看起来像是c79dc19,这就是它出现在您的历史记录中的原因。

最有可能的是,要么分支真正开始于c79dc19(因此它已经c79dc19在 master 上),要么分支在其头部时被合并到 master 作为快进。


工作插图:

  1. 初始状态

    fe62 <=master <=HEAD
    
  2. 新提交

    fe62 <- c79d <=master <=HEAD
    
  3. 结帐新分支

    fe62 <- c79d <=master <=branch <=HEAD
    
  4. 修改(在分支上)给出一个新的提交0c81,它在该分支上替换但 改变c79dmaster

    fe62 <- c79d <=master
         \- 0c81 <=branch <=HEAD
    
于 2016-11-09T18:34:49.420 回答
1

很难 100% 确定,但这种情况经常发生,所以这可能是正确的答案。

您提到您只有一个分支,名为master. 我相信你!但是你不只有一个存储库——或者更准确地说,你有你的克隆,然后还有一些其他的克隆,可能在你调用origin的某个中央服务器(如 GitHub 或公司服务器)上的远程。您将提交发送到服务器,并从服务器获取提交。

您还提到使用git commit --amend. 请参阅git commit --amend 究竟是如何工作的?(如Jubobs 的评论)了解详细信息,但简而言之,这不会更改提交,它只是将其推到一边以支持新的替换提交。不过,大概您已经推送了原始提交——所以现在它在另一个master存储库的分支中。

所以你现在有0c81926作为你的尖端master,而他们(起源)有c79dc19。然后,您进行了新的提交f6429eb,以便您master指出这一点。

然后,我打赌你跑了git pull(很可能你没有配置或指示你git pull这样做git rebase)。紧随git fetch其后的是git merge。用你的git fetch遥控器检查,origin发现 master指向 commit c79dc19git merge运行的git pull他们的分支与您的分支合并,产生 merge commit 706b1ef

最后,这意味着您确实有两个不同的分支:master 和 master。只是其中一个是你的师父,一个是别人的师父。

请注意,您可以摆脱提交c79dc19 合并,例如,使用git rebase -i fe6263e(就在混乱开始之前的点):删除不需要的额外提交,并让git rebase剩余的历史变平并省略合并。(或者,使用Jeff Puckett II 的回答中的方法。)但是,一旦你这样做,你的历史就会与历史不同origin他们有一个你没有的提交(c79dc19你试图摆脱的那个) . 因此,如果不强制推送,您将无法推送(可选地,“强制使用租约”,期望它们masterc79dc19,以确保自您上次检查以来他们没有获得更多提交)。

于 2016-11-09T19:21:03.153 回答