Git:这个分叉是怎么发生的?
Git: how this bifurcation happen?
情况
- 我有一个本地 Git 存储库。
我只有在分支上: master
.
我以前有另一个分支,但我把它合并到master
,然后删除了。
这样合并和删除的分支从fe6263e
.
分叉
0c81926
是对 c79dc19
的 --amend
没有标签或任何其他指向 c79dc19
的链接。我知道如果某个对象指向修改后的提交,则此类提交将继续显示在历史记录中。但事实并非如此。
问题
为什么历史线没有变平?
为什么仍然显示 c79dc19
?
这是怎么发生的?
正如我提到的,没有任何指向它,我做了一个 git -gc
来清理任何挂起的提交。
There is no tag nor any other [commit] pointing to c79dc19
历史不是这样的。
试试 运行 git show HEAD
- 它会显示合并的两个父项是什么。从你的图表来看,其中一个是 c79dc19
,这就是它出现在你的历史记录中的原因。
最有可能的是,分支确实是从 c79dc19
开始的(所以在 master 上 已经 ),或者分支作为快进合并到 master当 c79dc19
是它的头时。
已完成的插图:
初始状态
fe62 <=master <=HEAD
新提交
fe62 <- c79d <=master <=HEAD
签出新分支
fe62 <- c79d <=master <=branch <=HEAD
amend(在分支上)给出了一个新的提交 0c81
replaces c79d
在该分支上但是 没有改变 master
fe62 <- c79d <=master
\- 0c81 <=branch <=HEAD
您在 c79
从 master 创建了新分支,因此 master 继续指向那里。然后你从新分支提交了修改,因此主分支和新分支有不同的历史。
需要注意的一点是,修改实际上并没有修改提交。提交是不可变的。一个修正案基于另一个修正案创建一个新的提交。
如果你想压扁它,那么将 master 指向上一个提交并合并到 tip。
git checkout -b temp
git branch -f master fe6263e
git checkout master
git merge f6429eb
很难 100% 确定,但这种情况经常发生,所以这 可能 是正确答案。
您提到您只有一个 b运行ch,名为 master
。我相信你!但是您不只有一个 存储库 — 或者更准确地说,您有您的克隆,然后还有其他克隆,可能在您调用 origin
的遥控器上中央服务器,例如 GitHub 或企业服务器。您将提交发送到服务器,并从服务器获取提交。
您还提到使用 git commit --amend
。有关详细信息,请参阅 How does git commit --amend work, exactly? (as in ),但简而言之,这不会 更改 提交,它只是 将其推到一边 以支持新的替换提交。不过,据推测,您已经推送了原始提交——所以现在它位于 other 存储库中的 master
b运行ch 中。
所以你现在有 0c81926
作为你 master
的尖端,而他们(来源)有 c79dc19
。然后你做了新的提交 f6429eb
,所以你的 master
指向那个。
那么,我打赌你 运行 git pull
(很可能你没有配置或指示你的 git pull
做 git rebase
)。这个 运行 git fetch
后跟 git merge
。 git fetch
检查了您的遥控器 origin
,发现 its master
指向提交 c79dc19
。 git pull
运行合并他们的b运行ch和你的bgit merge
=82=]ch,生成合并提交 706b1ef
.
最后,这意味着你确实有两个不同的b运行ches:master和master。只不过其中一个是你的师父,一个是别人的师父
请注意,您可以摆脱提交 c79dc19
和 合并,例如,使用 git rebase -i fe6263e
(混乱开始之前的那个点):删除不需要的额外提交,并让 git rebase
展平剩余的历史记录并省略合并。 (或者,使用 中的方法。)但是,一旦你这样做,你的历史将与 origin
上的历史 不同 :他们有一个提交(与您试图摆脱的 c79dc19
相同)您没有。因此,您将无法在不强制推送的情况下推送(可选,"force with lease",期望他们的 master
为 c79dc19
,以确保自上次以来他们没有获得更多提交你检查的时间)。
情况
- 我有一个本地 Git 存储库。
我只有在分支上:
master
.我以前有另一个分支,但我把它合并到
master
,然后删除了。这样合并和删除的分支从
fe6263e
. 分叉
0c81926
是对c79dc19
的 --amend
没有标签或任何其他指向
c79dc19
的链接。我知道如果某个对象指向修改后的提交,则此类提交将继续显示在历史记录中。但事实并非如此。
问题
为什么历史线没有变平?
为什么仍然显示
c79dc19
?这是怎么发生的?
正如我提到的,没有任何指向它,我做了一个 git -gc
来清理任何挂起的提交。
There is no tag nor any other [commit] pointing to
c79dc19
历史不是这样的。
试试 运行 git show HEAD
- 它会显示合并的两个父项是什么。从你的图表来看,其中一个是 c79dc19
,这就是它出现在你的历史记录中的原因。
最有可能的是,分支确实是从 c79dc19
开始的(所以在 master 上 已经 ),或者分支作为快进合并到 master当 c79dc19
是它的头时。
已完成的插图:
初始状态
fe62 <=master <=HEAD
新提交
fe62 <- c79d <=master <=HEAD
签出新分支
fe62 <- c79d <=master <=branch <=HEAD
amend(在分支上)给出了一个新的提交
0c81
replacesc79d
在该分支上但是 没有改变master
fe62 <- c79d <=master \- 0c81 <=branch <=HEAD
您在 c79
从 master 创建了新分支,因此 master 继续指向那里。然后你从新分支提交了修改,因此主分支和新分支有不同的历史。
需要注意的一点是,修改实际上并没有修改提交。提交是不可变的。一个修正案基于另一个修正案创建一个新的提交。
如果你想压扁它,那么将 master 指向上一个提交并合并到 tip。
git checkout -b temp
git branch -f master fe6263e
git checkout master
git merge f6429eb
很难 100% 确定,但这种情况经常发生,所以这 可能 是正确答案。
您提到您只有一个 b运行ch,名为 master
。我相信你!但是您不只有一个 存储库 — 或者更准确地说,您有您的克隆,然后还有其他克隆,可能在您调用 origin
的遥控器上中央服务器,例如 GitHub 或企业服务器。您将提交发送到服务器,并从服务器获取提交。
您还提到使用 git commit --amend
。有关详细信息,请参阅 How does git commit --amend work, exactly? (as in master
b运行ch 中。
所以你现在有 0c81926
作为你 master
的尖端,而他们(来源)有 c79dc19
。然后你做了新的提交 f6429eb
,所以你的 master
指向那个。
那么,我打赌你 运行 git pull
(很可能你没有配置或指示你的 git pull
做 git rebase
)。这个 运行 git fetch
后跟 git merge
。 git fetch
检查了您的遥控器 origin
,发现 its master
指向提交 c79dc19
。 git pull
运行合并他们的b运行ch和你的bgit merge
=82=]ch,生成合并提交 706b1ef
.
最后,这意味着你确实有两个不同的b运行ches:master和master。只不过其中一个是你的师父,一个是别人的师父
请注意,您可以摆脱提交 c79dc19
和 合并,例如,使用 git rebase -i fe6263e
(混乱开始之前的那个点):删除不需要的额外提交,并让 git rebase
展平剩余的历史记录并省略合并。 (或者,使用 origin
上的历史 不同 :他们有一个提交(与您试图摆脱的 c79dc19
相同)您没有。因此,您将无法在不强制推送的情况下推送(可选,"force with lease",期望他们的 master
为 c79dc19
,以确保自上次以来他们没有获得更多提交你检查的时间)。