目录
[1.1 git也不是银弹](#1.1 git也不是银弹)
[3.1 创建git本地仓库](#3.1 创建git本地仓库)
[3.2 配置Git](#3.2 配置Git)
[3.3 认识工作区、暂存区、版本库](#3.3 认识工作区、暂存区、版本库)
[3.4 添加文件](#3.4 添加文件)
[3.5 Git文件目录](#3.5 Git文件目录)
[3.6 版本回退](#3.6 版本回退)
[3.7 撤销修改](#3.7 撤销修改)
[3.7.1 对于工作区的代码,还没有进行add操作](#3.7.1 对于工作区的代码,还没有进行add操作)
[3.7.2 已经 add,但没有 commit](#3.7.2 已经 add,但没有 commit)
[3.7.3 已经add,并且也 commit了](#3.7.3 已经add,并且也 commit了)
[3.8 删除文件](#3.8 删除文件)
[4.1 理解分支](#4.1 理解分支)
[4.2 创建分支(图的dev分支即为代码的test-branch分支)](#4.2 创建分支(图的dev分支即为代码的test-branch分支))
[4.3 切换分支](#4.3 切换分支)
[4.4 合并分支](#4.4 合并分支)
[4.5 删除分支](#4.5 删除分支)
[4.6 合并冲突](#4.6 合并冲突)
[4.7 分支管理策略](#4.7 分支管理策略)
[4.8 分支策略](#4.8 分支策略)
[4.8.1 master遇到bug并且分支正在开发该怎么处理?](#4.8.1 master遇到bug并且分支正在开发该怎么处理?)
[4.8.2 删除临时分支](#4.8.2 删除临时分支)
一、git的用处?
提出问题
不知道你工作或学习时,有没有遇到这样的情况:我们在编写各种⽂档时,为了防止文档丢失,更改 失误,失误后能恢复到原来的版本,不得不复制出⼀个副本,
比如:
"报告-v1"
"报告-v2"
"报告-v3"
"报告-确定版"
"报告-最终版"
"报告-究极进化版"
每个版本有各⾃的内容,但最终会只有⼀份报告需要被我们使用。 但在此之前的工作都需要这些不同版本的报告,于是每次都是复制粘贴副本,产出的文件就越来越多,⽂件多不是问题,问题是:随着版本数量的不断增多,你还记得这些版本各自都是修改了什么吗? 文档如此,我们写的项目代码,也是存在这个问题的!!
如何解决------版本控制器
为了能够更方便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你 了解到⼀个文件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录工程的每⼀次改动和 版本迭代的⼀个管理系统,同时也方便多人协同作业。 目前最主流的版本控制器就是Git。Git可以控制电脑上所有格式的⽂件,例如doc、excel、dwg、 dgn、rvt等等。对于我们开发⼈员来说,Git 最重要的就是可以帮助我们管理 软件开发项目 中的 源代码 文件!
1.1 git也不是银弹
需要注意的是:
还需要再明确⼀点,所有的版本控制系统,Git也不例外,其实只能跟踪⽂本⽂件的改动,⽐如TXT⽂ 件,网页,所有的程序代码等等。版本控制系统可以告诉你每次的改动,⽐如在第5⾏加了⼀个单词 "Linux",在第8⾏删了⼀个单词"Windows"。 ⽽图⽚、视频这些⼆进制⽂件,虽然也能由版本控制系统管理,但没法跟踪⽂件的变化,只能把⼆进 制⽂件每次改动串起来,也就是只知道图⽚从100KB改成了120KB,但到底改了啥,版本控制系统不 知道,也没法知道。
二、安装git
这里以centos为例,安装之前先检查一下是否已经安装:
命令行:
git --version
如果以安装会显示相关版本号:

安装git 命令行如下:
sudo yum install git -y

三、git基础操作
3.1 创建git本地仓库
创建一个Git本地仓库对应的命令为:git init,注意该命令是需要在文件目录下执行的:

创建后使用 ll -a 来查看.git文件。

ll -a
拆解一下:
- ll 是 ls -l 的别名,用于列出目录中的文件和子目录,并显示它们的详细信息,如权限,所有者,组,大小和最后修改时间。
- -a 是ls命令的一个选项,代表all,表示显示所有文件,包括以.开头的隐藏文件。
当然也可以使用 tree 命令查看 .git 里面是什么(前提:tree 命令需要手动安装)

不要手动 修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
3.2 配置Git
当安装Git后首先要做的事情是设置您的 用户名称 和 e-mail 地址。这是`非常重要的。配置命令为:
git config [--global] user.name 'your name'
git config [--global] user.email 'email@example.com'
其中 --global 是⼀个可选项。如果使用了该选项,表示这台机器上所有的Git仓库都会使用这个 配置。如果你希望在不同仓库中使用不同的 name 或 注意的是,执行命令时必须要在仓库里。
使用 git config -l 来查看当前git的配置。
以下是非全局的配置:

如果是想取消配置,那么如下:

以下是全局git的配置:

当然,如果是全局配置的话,想要删除这个配置,那么同样也要加上 --global,否则删除失效。

3.3 认识工作区、暂存区、版本库
- 工作区:是在电脑上你要写代码或文件的目录。
- 暂存区:英文叫 stage 或 index。⼀般存放在 .git 目录下的index文件(.git/index)中,我们把暂存区有时也叫作索引(index)。
- 版本库:又名仓库,英文名repository 。工作区有⼀个隐藏目录.git ,它不算工作区,而是Git的版本库。这个版本库里面的所有文件都可以被Git管理起来,每个⽂件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以"还原"。下⾯这个图展示了工作区、暂存区和版本库之间的关系:

图中左侧为工作区,右侧为版本库。Git 的版本库里存了很多东西,其中最重要的就是暂存区。
- 在创建Git版本库时,Git会为我们自动创建⼀个唯⼀的 master 分支,以及指向master的⼀个指针叫HEAD。(分支和HEAD的概念后面再说)。
- 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区目录树的⽂件索引会被更新。
- 当执行提交操作 git commit 时,master 分支 会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中。
由上述描述我们便能得知:通过新建或粘贴进目录的文件,并不能称之为向仓库中新增文件,而只是在工作区新增了文件。必须要通过使用 git add 和 git commit 命令才能将文件添加到仓库中
进行管理!!!
3.4 添加文件
在包含.git的目录下新建⼀个 ReadMe 文件,我们可以使用 git add 命令将文件添加到暂存区:
- 添加⼀个或多个⽂件到暂存区: git add [file1] [file2] ...
- 添加指定目录到暂存区,包括子目录: git add [dir]
- 添加当前目录下的所有⽂件改动到暂存区: git add .
再使用 git commit 命令将暂存区内容添加到本地仓库中:
提交暂存区全部内容到本地仓库中: git commit -m "message"
提交暂存区的指定文件到仓库区: git commit [file1] [file2] ... -m "message"
注意 git commit 后⾯的 -m 选项,要跟上描述本次提交的 message,由用户自己完成,这部分内容绝对不能省略,并要好好描述,是用来记录你的提交细节,是给我们人看的。
例如:

git commit 命令执行成功后会告诉我们,1个文件被改动(就是我们新添加的FirstFile⽂件),插入了两行内容(FirstFile 有两行内容)。
我们还可以多次 add 不同的文件,而只 commit ⼀次便可以提交所有文件,是因为需要提交的文件是通通被 add 到暂存区中,然后⼀次性 commit 暂存区的所有修改。如

截至目前为止,我们已经更够将代码直接提交至本地仓库了。我们可以使用 git log 命令,来查看
下历史提交记录:

该命令显示从最近到最远的提交日志,并且可以看到我们 commit 时的日志消息。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数:

需要说明的是,我们看到的⼀⼤串类似 23807c5...56eed6 的是每次提交的 commit id (版本
号),Git 的 commit id 不是1,2,3......递增的数字,⽽是⼀个 SHA1 计算出来的⼀个非常大的数字,⽤十六进制表示。
3.5 Git文件目录
java
[root@iZ0jl7jamelmq7pl8qut26Z gitcode]# tree .git/
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 54
│ │ └── 990fb04a5f51d9209095edc784aa8b546fd753
│ ├── 76
│ │ └── 18edfd30e673463bf8d35e8e5059609678a9aa
│ ├── 87
│ │ └── 9bc3d4d27694d78e531cb35a008a11cfeed3c2
│ ├── e6
│ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│ ├── ea
│ │ └── eeb89160446a3b6ff525a6fd7b2231326139c6
│ ├── f6
│ │ └── 98d3f274aa44d867c89912c82eeae58f52e8d9
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
- index 就是我们的暂存区,add 后的内容都是添加到这⾥的。
- HEAD 就是我们的默认指向 master 分支的指针

而我们master所指向的其实就是最新一次提交的commit id。

objects 为 Git 的对象库,里面包含了创建的各种版本库对象及内容。当执执行 git add 命令
时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新的对象中,就位于".git/objects"目录下。让我们来看看这些对象有何用处:

查找 object 时要将 commit id 分成2部分,其前2位是⽂件夹名称,后38位是⽂件名称。
找到这个文件之后,⼀般不能直接看到里面是什么,该类⽂件是经过 sha (安全哈希算法)加密过的⽂件,好在我们可以使⽤ git cat-file 命令来查看版本库对象的内容:

其中我们查看tree,发现就是我们提交的所有git记录。
总结⼀下,在本地的 git 仓库中,有⼏个文件或者目录很特殊
- index:暂存区, git add 后会更新该内容。
- HEAD: 默认指向 master 分⽀的⼀个指针。
- refs/heads/master: ⽂件⾥保存当前 master 分⽀的最新 commit id 。
- objects: 包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改
需要注意的是,git add 只是将数据添加到缓存区中,而不是添加到版本库中。只有commit才是添加到版本库中。
Git 比其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,而非⽂件。
什么是修改?比如你新增了一行,这就是⼀个修改,删除了一行,也是⼀个修改,更改了某些字符,也是⼀个修改,删了⼀些⼜加了⼀些,也是⼀个修改,甚⾄创建⼀个新⽂件,也算⼀个修改,
这里我们 对 1.txt 进行修改,作者这里使用的是finalshell,可以直接对其进行修改,我们对文件新增内容 ttt:

我们可以用 git status 命令用于查看你上次提交之后是否对文件进行再次修改,但是这往往不够,我们只知道改动的文件是什么,不知道改动的内容是什么,
所以 我们可以用命令 git diff [文件名] 来显示 工作区和暂存区文件的差异

当然 也可以用git diff head -- [file] 命令来查看工作区和版本库文件的区别。

3.6 版本回退
Git 能够管理⽂件的历史版本,这也是版本控制器重要的能力。如果有⼀天你发现
之前前的⼯作做的出现了很⼤的问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本回退的功能了。
执行 git reset 命令⽤于回退版本,可以指定退回某⼀次提交的版本。要解释⼀下"回退"本质是
要将版本库中的内容进⾏回退,⼯作区或暂存区是否回退由命令参数决定:
git reset 命令语法格式为: git reset [ --soft | --mixed | --hard ] [HEAD]
- --soft 参数对于工作区和暂存区的内容都是不变,只是版本库回退到指定版本。
- --mixed 为默认选项,使用时可以不用带该参数,该参数将暂存区和版本库的内容退回为指定提交版本。
- --hard 参数将暂存区和工作区以及版本库都回退到指定版本,切记工作区有未提交的代码时不要使用这个命令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数前一定要慎重。
HEAD 说明:
- 可直接写成 commit id,表示指定退回的版本
- HEAD 表示当前版本
- HEAD^ 上⼀个版本
- HEAD^^ 上上⼀个版本
- 以此类推
示例:
这里我们就通过 git log --pretty=oneline 的方法来获取每次提交的日志,由于这里显示的commit id是从最新到最老的,所以我们这里拿最老的commit id,回退到最初的状态:

当然了,如果想反悔了呢?那么我们就继续从当前终端上获取刚刚显示的 最新的commit id,即可进行回滚:

当然了,有时候可能终端上找不到刚刚那个commit id 了,比如各种意外情况,进行了 clear 清屏操作,或者是 掉电之类的,
git 也会提供对应的解决方案,使用 git reflog 方法可以查看本地提交的所有git记录。

值得说的是,Git 的版本回退速度非常快,因为Git在内部有个指向当前分支(此处是master)的HEAD 指针, refs/heads/master 文件⾥保存当前 master 分⽀的最新 commit id 。当我们
在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的 version,可以简单理解
成如下示意图:

3.7 撤销修改
3.7.1 对于工作区的代码,还没有进行add操作
可能有人会说,使用 git diff xxx 命令,来看看区别在哪,但是如果你书写了很多代码,这时候就不太好撤销了,因为人工可能有出错的可能的,Git为我们提供了更好的方式:
git checkout -- [file]
该命令让工作区的文件回到最近一次 add 或 commit 时的状态。需要注意的是,**git checkout -- [file]**该命令中的 -- 很重要,切记不能忽略,一旦忽略,该命令就变为其他意思了。
示例如下:

使用 该命令后,1.txt 文件中的内容全部都回退到改动之前的版本了。
3.7.2 已经 add,但没有 commit
直接使用之前学过的 git reset操作:

3.7.3 已经add,并且也 commit了
不要担心,我们可以 git reset --hard HEAD^ 回退到上⼀个版本!不过,这是有条件的,就是
你还没有把⾃⼰的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后⾯会讲到远程版本库,⼀旦你推送到远程版本库,那就没办法了。

分析:之前版本1.txt 是有 ttt和 222的,现在变回ttt了。

3.8 删除文件
在git中,删除也是一个修改操作,比如 我们要删除这个2.txt该如何删除呢?
第一种方式需要3步,先在工作区 利用 rm 命令删除文件,然后将其状态add进暂存区,最后commit。

对于第⼀种情况,很明显是没有删完,我们只删除了⼯作区的⽂件。这时就需要使用 git rm 将文件从暂存区和工作区中删除,并且 commit:

可以看出,git rm 这个命令,相比于第一种情况,省了add的过程。
四、Git分支管理
4.1 理解分支
在版本回退里,你已经知道,每次提交,Git都把它们串成⼀条时间线,这条时间线就可以理解为是⼀个分支。截至到目前,只有⼀条时间线,在Git⾥,这个分⽀叫主分⽀,即 master 分支。再来理解⼀下HEAD,HEAD 严格来说不是指向提交,⽽是指向 master,master才是指向提交的,所以,HEAD 指向的就是当前分支。
每次提交,master 分支都会向前移动⼀步,这样,随着你不断提交,master分⽀的线也越来越长,⽽HEAD只要⼀直指向master分支即可指向当前分支。
通过查看当前的版本库,我们也能清晰的理出思路:

4.2 创建分支(图的dev分支即为代码的test-branch分支)
Git支持我们查看或创建其他分支,在这里我们来创建第一个自己的分支,对应的命令为:

当我们创建新的分支后,Git新建了一个指针叫 dev,* 表示当前HEAD指向的分支是master分支。另外,可以通过目录结构发现,新的 dev 分支。

发现目前 dev 和 master 指向同一个修改。并且HEAD目前是指向master的:

用一张图总结:

4.3 切换分支
那如何切换到dev分支下进行开发呢?使用 git checkout 命令即可:

如图所示,为切换后的效果,HEAD指向当前分支:

现在我们在dev分支下,进行修改文件,并进行commit操作,观察master分支下是否能感应到?
我们使用finalshell,在1.txt上进行添加内容,但是切换到master分支后查看文件发现并没有添加。

而刚刚我们在test-branch上修改的是存在的:

当切换到master分支的时候,图中的HEAD指针就会指向master,当然就看不到修改了。

这是就需要我们进行手动的合并分支操作。
4.4 合并分支
为了在 master 主分⽀上能看到新的提交,就需要将 dev 分⽀合并到 master 分支,示例如下:

git merge 命令⽤于合并指定分支到当前分支。合并后,master 就能看到 test-branch 分支提交的内容了。此时的状态如图如下所示:

Fast-forward 代表"快进模式",也就是直接把master指向dev的当前提交,所以合并速度⾮常快。
当然,也不是每次合并都能 Fast-forward,我们后面会讲其他⽅式的合并。
4.5 删除分支
合并完成后,test-branch 分支对于我们来说已经没用了,那么test-branch就可以被删除掉,注意如果当前正处于某分支下,就不能删除当前分支,如:

而可以在其他分支下删除当前分⽀,如

此时的状态如图如下所示:

4.6 合并冲突
在实际分⽀合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。
为了演示这问题,创建⼀个新的分支 dev1 ,并切换至目标分⽀,我们可以使⽤
git checkout -b dev1
一步完成创建并切换的动作,示例如下:

在dev1分支下修改1.txt文件,并进行commit提交:

此时在master分支上,我们再次对1.txt文件进行修改,并且进行commit操作:

这个时候,dev1和master分支上都有了新的提交,如下所示:

这时候git合并冲突的时候就会出现如下的问题:

发现 ReadMe 文件有冲突后,可以直接查看文件内容,要说的是Git 会⽤ <<<<<<<,=======,>>>>>>>来标记出不同分⽀的冲突内容,如下所示:

此时我们需要手动调整冲突代码,并需要再次提交修正后的结果。(注意:再次提交非常重要,切勿忘记)。

此时冲突就解决了,这时候git的状态变为如下所示:

使用带参数的git log 也可以看到分支的合并情况:

4.7 分支管理策略
通常合并分⽀时,如果可能,Git 会采⽤ Fast forward 模式。还记得如果我们采用 Fast
forward 模式之后,形成的合并结果是什么呢?回顾⼀下

如下所示:

在这种 Fast forward 模式下,查看分支历史时,会丢掉分支信息,看不出来最新提交到底是 merge 进来的还是正常提交的。
虽然在合并冲突部分,我们可以看到解决冲突问题的状态,这存在一些弊端(不方便排查是谁干的):

Git 支持我们强制禁⽤ Fast forward 模式,那么就会在 merge 时生成⼀个新的 commit ,这样,
从分支历史上就可以看出分支信息。
下面我们实战⼀下 --no-ff 方式的 git merge 。首先,创建新的分支 dev2 ,并切换至新的分
⽀:

请注意 --no-ff 参数,表⽰禁⽤ Fast forward 模式。禁用 Fast forward 模式后合并会创建
⼀个新的 commit ,所以加上 -m 参数,把描述写进去。
合并后,查看分支历史:
可以看到,不使⽤ Fast forward 模式,merge后就像这样:

所以在合并分支时,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾
经做过合并,⽽ fast forward 合并就看不出来曾经做过合并:
4.8 分支策略
在实际开发中,我们应该按照几个基本原则进行分⽀管理:
⾸先,master分支应该是非常稳定的,也就是仅⽤来发布新版本,平时不能在上面干活;
那在哪干活呢?⼲活都在dev分支上,也就是说,dev分⽀是不稳定的,到某个时候,⽐如1.0版本发布时,再把dev分⽀合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个⼈都在dev分支上干活,每个⼈都有自己的分支,时不时地往dev分支上合并就可以了。
所以,团队合作的分支看起来就像这样:
4.8.1 master遇到bug并且分支正在开发该怎么处理?
假如我们现在正在 dev2 分支上进行开发,开发到一半,突然发现master分支上面有bug,需要解决。在git中,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
可现在 dev2 代码在工作区中开发了一半,还无法提交,怎么办呢?(需要注意的是,在dev2分支未进行commit操作的时候,dev2和master上所看到的内容都是一样的)

Git 提供了 git stash 命令,可以将当前的⼯作区信息进⾏储藏,被储藏的内容可以在将来某个时
间恢复出来:

存储dev2 工作区内容后,由于我们要基于master分支修复bug,所以需要切回master分支,再新建一个临时的分支来修复bug,示例如下:

修复完成后,切换到master分支,并完成合并,最后删除fix-bug分支:

至此,bug的修复工作已经做完了,我们还要继续回到dev2分支上进行开发:

工作区是干净的,刚刚的写的代码去哪了? 我们使用git stash list 命令查看:

⼯作现场还在,Git 把 stash内容存在某个地⽅了,但是需要恢复⼀下,如何恢复现场呢?我们可以使 ⽤ git stash pop 命令,恢复的同时会把 stash 也删了,示例如下:

再次查看的时候,我们已经发现已经没有现场可以恢复了:

另外,恢复现场也可以采用 git stash apply 恢复,但是恢复后,stash内容并不删除,你需要
⽤ git stash drop 来删除;
当然,你可以多次stash,恢复的时候,先⽤ git stash list 查看,然后恢复指定的stash,⽤命令
git stash apply stash@{0} ,这部分就不细讲了。
恢复完代码之后我们便可以继续完成开发,开发完成后便可以进行提交,例如:

但我们注意到了,修复 bug 的内容,并没有在 dev2 上显示。此时的状态图为:

Master 分支 目前 最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们
在 dev2 中当然看不见修复 bug 的相关代码。
我们的最终目的的是要让 master 合并 dev2 分支的,那么正常情况下我们切回 master 分⽀直接合
并即可,但这样其实是有⼀定⻛险的。
是因为在合并分支时可能会有冲突,⽽代码冲突需要我们手动解决(在 master 上解决)。我们无法保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项⽬中,代码冲突不只一两行那么简单,有可能几十上百行,甚至更多,解决的过程中难免⼿误出错,导致错误的代码被合并到 master 上。此时的状态为:

解决这个问题的⼀个好的建议就是:最好在自己的分⽀上合并下 master ,再让 master 去合并
dev ,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响 master 。
第一步:dev合并master分支,用于解决合并冲突。

第二步:合并冲突已解决,master合并dev。

代码如下:
dev2上合并master,并进行解决冲突:

切回master分支,进行合并dev2分支:

4.8.2 删除临时分支
软件开发中,总有⽆穷⽆尽的新的功能要不断添加进来。
添加⼀个新功能时,你肯定不希望因为⼀些实验性质的代码,把主分⽀搞乱了,所以,每添加⼀个新功能,最好新建⼀个分支,我们可以将其称之为 feature 分支,在上面开发,完成后,合并,最
后,删除该 feature 分支。
可是,如果我们今天正在某个 feature 分支上开发了⼀半,被产品经理突然叫停,说是要停止新功
能的开发。虽然白干了,但是这个 feature 分支还是必须就地销毁,留着无用了。这时使⽤传统
的 git branch -d 命令删除分⽀的⽅法是不行的。演示如下:

由于这里的newdev分支上的内容已经是commit状态了,所以无法通过 -d 进行 删除,
只能通过 -D 进行删除。

五、总结
分支在实际中有什么⽤呢?假设你准备开发⼀个新功能,但是需要两周才能完成,第⼀周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别⼈不能⼲活了。如果等代码全
部写完再⼀次提交,⼜存在丢失每天进度的巨大⻛险。
现在有了分⽀,就不⽤怕了。你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分支上,这样,既安全,⼜不影响别人⼯作。
并且 Git ⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成!⽆论你的版本库是1个⽂件还是1万个⽂件。