如何删除没有名称的 Git 分支
How do I delete a Git branch that has no name
我不确定这是怎么发生的。但是在 rebase 之后,我有一个无名的分离分支,它是 master 的部分副本。我可能在从一个分支的一个分支变基时犯了一些错误。那么基本上如何删除提示为 0ac0e6b 的分支?
* 11e604e (HEAD -> master) Some comment
* a50932a Another comment
....
....
* 0d85332 Activities: service <-- dupes below
* 5323616 Activities: setup <--
* e4f5063 Results: fix <--
* 5bf3ec0 Composer: update
| * 0ac0e6b XController Setup (tag: sometag) <-- THIS BRANCH HAS NO NAME
| * a34b800
| * dccbd3b
| * 020b15e Activities: service <-- dupes above
| * f4231cf Activities: setup <--
| * 118536f Results: fix <--
|/
* c42ad6f Some comment
[原来这个问题是分支中的一个标签似乎阻止它被删除 - 我会把它留在这里以防有人遇到同样的问题。删除标签,我案例中的分支就消失了。在编辑中添加了标签。]
如果要清理存储库,可以使用 git gc
command。 gc
代表垃圾收集器,它删除不必要的(即不属于任何分支的提交)提交。
正如您所发现的,对于 Git 到 首先找到 一个提交,它必须查看 一些 提交的名称。在本例中,这是一个标签名称。
最奇怪的部分是这个 git log --all --decorate --oneline --graph
输出,我将把它剪下来只有两个关键行(和一个“...”):
* 11e604e (HEAD -> master) Some comment
...
| * 0ac0e6b XController Setup
第一个告诉我们您正在使用 --decorate
:提交显示的名称是 Git 找到的在括号中提交。
然后我们进入神秘提交。由于您使用的是 --decorate
,因此 应该 阅读:
| * 0ac0e6b (tag: sometag) XController Setup
这会告诉我们标签 sometag
是 Git 找到这个新引入的提交流的名称。
一旦 Git 找到任何特定的提交,当然,它会使用该提交的父哈希 ID 来查找提交的父,因此:
| * a34b800
| * dccbd3b
等等并不神秘:它们是通过提交 0ac0e6b
的散列 ID(可以说是 "true name")找到的。特别是,a34b800
是 0ac0e6b
的父级,dccbd3b
是 a34b800
的父级,依此类推。
这实际上是对 Git
的关键洞察
值得考虑一下:Git 中的分支名称不会创建 提交。它只是让 Git 找到 提交,并且它通过直接指向一个 - 只是 一个 - 提交来做到这一点。 Git 将此指向提交称为分支的 提示。
为了向现有分支添加新提交,Git 所做的是:
编写一个新的提交,其中包含源快照、作者姓名以及您在 git log
中看到的所有其他常见元数据。这些元数据之一是提交的 父 ID 哈希。
新提交的父ID是分支名称指向的提交:
... <--commit <--commit <--current-tip-commit <-- branchname
\
new-commit-just-made
并且,现在 new 提交存在,更改 分支名称中存储的哈希。分支名称不再指向之前的提示提交。现在它指向您刚刚进行的新提交!
... <--commit <--commit <--current-tip-commit
\
new-commit-just-made <-- branchname
当 Git 对分支名称进行所有这些奇特的移动时,只有一个名称实际移动。那就是 git status
说你是 "on" 的分支,就像 git status
说 on branch master
一样。 所有其他现有名称未受干扰。如果其中任何一个指向当前提交,它们将继续指向当前提交。
这是 git rebase
最常出错的地方,它通过 复制 提交来工作——一些提交字符串由您传递给 [=28= 的参数计算得出]—闪亮的新提交(无论如何我们希望)是对旧的沉闷提交的改进。然后它移动一个分支名称。只要那个分支名称是 only 找到旧提交的方法,现在 Git 只能找到 new 提交,看起来提交已经改变了——但他们没有!旧的还在里面。
一旦我们有了第二个名字——分支名称、标签名称、refs/stash
引用、远程跟踪名称,或者你出于某种原因发明的任何新事物——Git 通过它找到old 提交,但是,它们在 git log --all
中。现在你必须想办法让那些名字移动;如果它们是标签名称,移动它们通常不是一个好主意。
我不确定这是怎么发生的。但是在 rebase 之后,我有一个无名的分离分支,它是 master 的部分副本。我可能在从一个分支的一个分支变基时犯了一些错误。那么基本上如何删除提示为 0ac0e6b 的分支?
* 11e604e (HEAD -> master) Some comment
* a50932a Another comment
....
....
* 0d85332 Activities: service <-- dupes below
* 5323616 Activities: setup <--
* e4f5063 Results: fix <--
* 5bf3ec0 Composer: update
| * 0ac0e6b XController Setup (tag: sometag) <-- THIS BRANCH HAS NO NAME
| * a34b800
| * dccbd3b
| * 020b15e Activities: service <-- dupes above
| * f4231cf Activities: setup <--
| * 118536f Results: fix <--
|/
* c42ad6f Some comment
[原来这个问题是分支中的一个标签似乎阻止它被删除 - 我会把它留在这里以防有人遇到同样的问题。删除标签,我案例中的分支就消失了。在编辑中添加了标签。]
如果要清理存储库,可以使用 git gc
command。 gc
代表垃圾收集器,它删除不必要的(即不属于任何分支的提交)提交。
正如您所发现的,对于 Git 到 首先找到 一个提交,它必须查看 一些 提交的名称。在本例中,这是一个标签名称。
最奇怪的部分是这个 git log --all --decorate --oneline --graph
输出,我将把它剪下来只有两个关键行(和一个“...”):
* 11e604e (HEAD -> master) Some comment ... | * 0ac0e6b XController Setup
第一个告诉我们您正在使用 --decorate
:提交显示的名称是 Git 找到的在括号中提交。
然后我们进入神秘提交。由于您使用的是 --decorate
,因此 应该 阅读:
| * 0ac0e6b (tag: sometag) XController Setup
这会告诉我们标签 sometag
是 Git 找到这个新引入的提交流的名称。
一旦 Git 找到任何特定的提交,当然,它会使用该提交的父哈希 ID 来查找提交的父,因此:
| * a34b800
| * dccbd3b
等等并不神秘:它们是通过提交 0ac0e6b
的散列 ID(可以说是 "true name")找到的。特别是,a34b800
是 0ac0e6b
的父级,dccbd3b
是 a34b800
的父级,依此类推。
这实际上是对 Git
的关键洞察值得考虑一下:Git 中的分支名称不会创建 提交。它只是让 Git 找到 提交,并且它通过直接指向一个 - 只是 一个 - 提交来做到这一点。 Git 将此指向提交称为分支的 提示。
为了向现有分支添加新提交,Git 所做的是:
编写一个新的提交,其中包含源快照、作者姓名以及您在
git log
中看到的所有其他常见元数据。这些元数据之一是提交的 父 ID 哈希。新提交的父ID是分支名称指向的提交:
... <--commit <--commit <--current-tip-commit <-- branchname \ new-commit-just-made
并且,现在 new 提交存在,更改 分支名称中存储的哈希。分支名称不再指向之前的提示提交。现在它指向您刚刚进行的新提交!
... <--commit <--commit <--current-tip-commit \ new-commit-just-made <-- branchname
当 Git 对分支名称进行所有这些奇特的移动时,只有一个名称实际移动。那就是 git status
说你是 "on" 的分支,就像 git status
说 on branch master
一样。 所有其他现有名称未受干扰。如果其中任何一个指向当前提交,它们将继续指向当前提交。
这是 git rebase
最常出错的地方,它通过 复制 提交来工作——一些提交字符串由您传递给 [=28= 的参数计算得出]—闪亮的新提交(无论如何我们希望)是对旧的沉闷提交的改进。然后它移动一个分支名称。只要那个分支名称是 only 找到旧提交的方法,现在 Git 只能找到 new 提交,看起来提交已经改变了——但他们没有!旧的还在里面。
一旦我们有了第二个名字——分支名称、标签名称、refs/stash
引用、远程跟踪名称,或者你出于某种原因发明的任何新事物——Git 通过它找到old 提交,但是,它们在 git log --all
中。现在你必须想办法让那些名字移动;如果它们是标签名称,移动它们通常不是一个好主意。