我一直在寻找这个问题的答案,但我仍然不完全确定答案。 我发现的关于删除分支的大多数信息只不过是手册所说的副本(例如here on SO)。 我认为一个核心问题是我不确切知道Git中的一个分支是什么(即使有许多文章声称要解释这一点)。 我找到的唯一有用的信息是this SO answer和使用git安装的文档。
我的问题:
当我运行git branch -d BRANCH_NAME
时,
以及git branch -D BRANCH_NAME
的相同子请求。
我目前的理解:
首先我对分支的看法: 根据上下文,术语分支指的是指向某个提交的指针(严格称为分支头),或者指向导致该提交的提交列表
对于git branch -d BRANCH_NAME
:
对于git branch -D BRANCH_NAME
:
答案 0 :(得分:5)
无论是使用git branch -d
还是git branch -D
删除,git都不会删除提交,只会删除分支ref。请继续阅读,看看这意味着什么。
首先,我们将设置一个简单的演示历史记录。
$ touch initial ; git add initial ; git commit -m 'Initial commit'
[master (root-commit) 2182bb2] Initial commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 initial
$ git checkout -b mybranch
Switched to a new branch 'mybranch'
此时,master
和mybranch
都指向同一个
提交,我们至少可以通过两种方式进行验证。
$ git lola
* 2182bb2 (HEAD -> mybranch, master) Initial commit
请注意,git lola
是一个非标准但非常有用的别名,
相当于
$ git log --graph --decorate --pretty=oneline --abbrev-commit --all
* 2182bb2 (HEAD -> mybranch, master) Initial commit
我们将在mybranch
上创建新提交后查看另一种方式。
$ touch mybranch ; git add mybranch ; git commit -m 'My branch'
[mybranch 7143aa4] My branch
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 mybranch
执行此操作后,我们确实在多个分支上进行了多次提交。
$ git lola
* 7143aa4 (HEAD -> mybranch) My branch
* 2182bb2 (master) Initial commit
我们现在可以看看git如何在幕后实现这一点。
$ ls -R .git/refs
.git/refs:
heads tags
.git/refs/heads:
master mybranch
.git/refs/tags:
好奇有些文件与我们的分支同名。 在里面看,我们看到了
$ cat .git/refs/heads/master .git/refs/heads/mybranch
2182bb2d5a0a7f57d0b74e95d37e208dac41f95b
2182bb2d5a0a7f57d0b74e95d37e208dac41f95b
因此git将refs实现为名称匹配的特定位置的文件
分支名称和包含SHA1
某些提交的哈希值。注意git lola
(2182bb2
)输出中的缩写哈希是上面cat
输出的前导。
将git refs想象成简单的指针,为存储库历史记录中的特定提交提供人类可读的名称。
现在,如果我们切换回master
并点击mybranch
$ git checkout master ; git branch -D mybranch
Switched to branch 'master'
Deleted branch mybranch (was 7143aa4).
我们看到裁判消失了
$ ls -R .git/refs
.git/refs:
heads tags
.git/refs/heads:
master
.git/refs/tags:
但提交仍在那里。
$ git show --pretty=oneline 7143aa4
7143aa477735382e7a0ed11c9e4b66c1f27583df My branch
diff --git a/mybranch b/mybranch
new file mode 100644
index 0000000..e69de29
如果您想要mybranch
,则只需运行
$ git checkout -b mybranch 7143aa4
Switched to a new branch 'mybranch'
或
$ git branch mybranch 7143aa4
取决于,各自的输出差异表明,
是否要切换到分支。在后一种情况下,
你留在当前分支的地方,git lola
看起来像
$ git lola
* 7143aa4 (mybranch) My branch
* 2182bb2 (HEAD -> master) Initial commit
是的,即使您删除了使它们保持活动状态的指针,您的提交也会在中短暂停留。这在意外删除的情况下非常有用。另请参阅git reflog
和git gc
。
请注意,存储库中的SHA1哈希值会有所不同 因为你的姓名和电子邮件地址至少会有所不同 从我使用的。
为了完整起见,-d
和-D
之间的区别是小写版本稍微安全一些。
-d
--delete
删除分支。分支必须在其上游分支中完全合并,或者如果没有使用
HEAD
或--track
设置上游,则必须在--set-upstream
中合并。
-D
--delete --force
的快捷方式。
-f
--force
如果 branchname 已存在,请将 branchname 重置为 startpoint 。没有
-f
git branch拒绝更改现有分支。结合-d
(或--delete
),允许删除分支,无论其合并状态如何......
答案 1 :(得分:1)
删除分支后,提交仍然存在,直到下一次垃圾回收。 git branch -d
(和-D
)打印缩写的提交哈希,您可以将其用作git log
或git checkout
或git branch
的参数,这样就可以恢复已删除的分支。
-d
和-D
之间的唯一区别是git branch -d
不会让您删除未合并的分支(即可能会丢失提交)。