为什么删除分支后git个分支历史仍然存在
Why does git branch history remain when the branch has been deleted
我删除了 git 中的一个分支,并通过 运行 确认它不再存在:
git branch -a
但是,我仍然可以使用我的 Git GUI 工具查看分支,尽管没有标记。
这是标准行为吗?我期待那个分支的历史是它被合并到的分支的一部分。
那个分支的历史是它被合并到的分支的一部分。如果您 运行 git log
来自您合并到的分支,您将在您合并的分支中看到提交。他们是历史的一部分。
那你为什么还在"seeing the branch"?因为你看到的是一系列ancestor-descendant关系,而不是分支。
git 中的 "branch" 不是一系列提交。我们这样对待它,因为它对我们的心智模型有意义,但分支只是一个可移动的标签。它是分配给特定提交的名称。当您在分支 X 上工作并创建新提交时,git 创建该提交,将其 parent 设置为 X 指向的当前提交,然后移动分支 X 以指向新提交.
那么,假设您是分支主管。 Branch master 当前指向提交 1(我将使用数字来指代提交;git 使用散列,但没有区别)。你做了一些改变,运行git commit
。这意味着 git 创建一个新的提交,提交 2。提交 2 的 parent 是提交 1。然后将标签 master 移动到提交 2。所以如果你打开你的 git GUI 工具,您会看到 master 位于提交 2,然后在其下方有一行提交 1。那是因为 1 是 2 的 parent 提交。
现在假设您创建了一个新分支。你运行git branch new; git checkout new
。现在你站在新的分支上。新分支是从你站着创建的,所以它也指向提交 2。在你的 GUI 工具中你会看到 master 和 new 都指向提交 2。
现在做一些改变,运行git commit
。这将创建提交 3,其中提交 2 作为其 parent,并将分支标记 new 移至 3。分支标记 master 仍指向 2.
现在回去掌握,git checkout master
,然后做一些改变,git commit
。同样,新的提交(假设是 4),这个也有 2 作为它的 parent。在 GUI 工具中可以看到 3 和 4 都有一条线将它们连接到 2。
现在,与您的问题相关的部分。还在master,运行git merge new
。这将合并到新分支中。那么什么是 git 中的合并?合并只是一个提交,而不是有一个 parent 提交,有两个 parent 提交。当你 运行 git merge new
git 所做的是创建一个新的提交 5,并将 提交 3 和 4 设置为它的 parent s(4 因为它是 master 指向的那个,3 因为它是 new 指向的那个)。所以如果你打开你的 GUI 工具,你会看到你在这种情况下所期望看到的:master 指向 5,two lines from it, one to 4, and one to 3,因为 both 提交都是 5 的 parent。由于您没有告诉 git 其他情况,您仍然会看到标记为提交 3 的新分支。
现在,您创建的所有这些 git 历史记录完全独立于分支,如果您删除分支,它们仍然存在。请记住,分支只是附加到提交的标签。删除分支不会删除提交或其任何历史记录,它只会删除标签。所以现在你可以 运行 git branch -d new
,分支 new 将消失。但是,"in branch new" 的提交 3 仍将存在。 Commit 3 的 parent 仍然是 2,commit 3 仍然是 5 的 parent 之一。那么如果您查看 GUI 工具会发生什么?好吧,你会看到标记为 master 的提交 5,然后从它出来两行,将提交 4 和 3 标记为它的 parents,然后来自 4 和 3 的行将 2 标记为它们的 parent,然后是从 2 到 1 的一行。与删除新分支之前完全相同。
我希望这能说明问题。
我删除了 git 中的一个分支,并通过 运行 确认它不再存在:
git branch -a
但是,我仍然可以使用我的 Git GUI 工具查看分支,尽管没有标记。
这是标准行为吗?我期待那个分支的历史是它被合并到的分支的一部分。
那个分支的历史是它被合并到的分支的一部分。如果您 运行 git log
来自您合并到的分支,您将在您合并的分支中看到提交。他们是历史的一部分。
那你为什么还在"seeing the branch"?因为你看到的是一系列ancestor-descendant关系,而不是分支。
git 中的 "branch" 不是一系列提交。我们这样对待它,因为它对我们的心智模型有意义,但分支只是一个可移动的标签。它是分配给特定提交的名称。当您在分支 X 上工作并创建新提交时,git 创建该提交,将其 parent 设置为 X 指向的当前提交,然后移动分支 X 以指向新提交.
那么,假设您是分支主管。 Branch master 当前指向提交 1(我将使用数字来指代提交;git 使用散列,但没有区别)。你做了一些改变,运行git commit
。这意味着 git 创建一个新的提交,提交 2。提交 2 的 parent 是提交 1。然后将标签 master 移动到提交 2。所以如果你打开你的 git GUI 工具,您会看到 master 位于提交 2,然后在其下方有一行提交 1。那是因为 1 是 2 的 parent 提交。
现在假设您创建了一个新分支。你运行git branch new; git checkout new
。现在你站在新的分支上。新分支是从你站着创建的,所以它也指向提交 2。在你的 GUI 工具中你会看到 master 和 new 都指向提交 2。
现在做一些改变,运行git commit
。这将创建提交 3,其中提交 2 作为其 parent,并将分支标记 new 移至 3。分支标记 master 仍指向 2.
现在回去掌握,git checkout master
,然后做一些改变,git commit
。同样,新的提交(假设是 4),这个也有 2 作为它的 parent。在 GUI 工具中可以看到 3 和 4 都有一条线将它们连接到 2。
现在,与您的问题相关的部分。还在master,运行git merge new
。这将合并到新分支中。那么什么是 git 中的合并?合并只是一个提交,而不是有一个 parent 提交,有两个 parent 提交。当你 运行 git merge new
git 所做的是创建一个新的提交 5,并将 提交 3 和 4 设置为它的 parent s(4 因为它是 master 指向的那个,3 因为它是 new 指向的那个)。所以如果你打开你的 GUI 工具,你会看到你在这种情况下所期望看到的:master 指向 5,two lines from it, one to 4, and one to 3,因为 both 提交都是 5 的 parent。由于您没有告诉 git 其他情况,您仍然会看到标记为提交 3 的新分支。
现在,您创建的所有这些 git 历史记录完全独立于分支,如果您删除分支,它们仍然存在。请记住,分支只是附加到提交的标签。删除分支不会删除提交或其任何历史记录,它只会删除标签。所以现在你可以 运行 git branch -d new
,分支 new 将消失。但是,"in branch new" 的提交 3 仍将存在。 Commit 3 的 parent 仍然是 2,commit 3 仍然是 5 的 parent 之一。那么如果您查看 GUI 工具会发生什么?好吧,你会看到标记为 master 的提交 5,然后从它出来两行,将提交 4 和 3 标记为它的 parents,然后来自 4 和 3 的行将 2 标记为它们的 parent,然后是从 2 到 1 的一行。与删除新分支之前完全相同。
我希望这能说明问题。