一、Git是什么?

1.Git能解决的事情

Git是版本管理系统。它具有以下功能:

  • 更方便地记录文件状态。如果使用手动备份,如果某个时间的备份丢失了,那么就没法返回到这个时间点对应的状态了,并且手动备份管理起来也很麻烦。如果使用Git,不仅只需要一个工作文件夹,也可以很方便地返回各个修改点的文件状态。
  • 可以多人协作修改文件。一般情况下,多人协作修改文件时,只能口头询问然后手动修改,使用Git,可以自动汇总多人的修改。
  • 能记录修改的原因。手动修改文件时,只能询问修改人,而Git可以进行记录,需要的时候查一下历史记录就可以了。

2.作为交流场所的Github和Bitbucket

GithubBitbucket是常用的代码托管服务。除了托管服务之外,他们还提供互动交流的功能。这个教程中,我们重点介绍Github。你可以点击这里来访问Github。

二、一个人独自使用Git

1.安装可以简单使用Git的工具

在本教程中,我们用SourceTree来进行教学。相比较直接使用命令行进行操作,SourceTree的图形化界面更方便新手的操作。你可以点击这里下载。

安装教程什么的就不需要说明了吧?;)

2.创建仓库

仓库,顾名思义,就是存放各种东西的地方,它可以保存过去文件的各种状态。我们接下来的各种操作,都要在仓库之间操作。我们先从创建一个本地仓库开始。

先在本地创建一个文件夹,我们这里把它命名为“sample”。接下来我们把这个文件夹初始化为仓库,打开SourceTree,点击菜单栏下方的“Create”,点击“浏览”,选择刚刚的文件夹。然后,在第二行输入仓库的名字,点击“创建”按钮。如果提示路径重复,则点击“是”进行覆盖。这样,我们就创建好了一个空仓库。

如何确认仓库是否已经初始化了呢?我们先在Windows打开“显示隐藏文件”这个选项,然后查看刚刚的文件夹,目录下是否有一个叫 .git的文件夹。如果有的话,那么就证明已经创建好了。在 .git这个文件夹里,存储着过去的文件与目录的状态。

3.提交

我们先想象一个准备什锦烧原料的过程,在这个过程中,用相机记录下来各个过程。在上面的过程可以形容如下:

(1)把原料放在碗里,按照比例混合好;

(2)把装着混合好的原料的碗放上摄影台;

(3)拍摄此刻原料的状态。

在这个过程中,我们一共经历了三个状态:混合原料(操作),放上摄影台(暂存),拍摄照片(提交)。而Git中提交代码的操作就是这样的,先对源代码进行操作,将操作存入暂存区后再进行提交。

SourceTree可以察觉仓库内的任何变化,点击左侧“WORKSPACE”下的History按钮,我们可以很方便地查看仓库中的操作记录。
https://images.shojola.top/SourceTree_History_d41d8cd98f00b204e9800998ecf8427e.png

在SourceTree中,上述操作过程是这样完成的:

编辑好代码之后,先点击“暂存所有”,将文件保存到暂存区。暂存好的文件会转移到上方“已暂存文件”一栏中。https://images.shojola.top/SourceTree_Staging_d41d8cd98f00b204e9800998ecf8427e.png

暂存完毕后点击左上角的“提交”,然后在界面最下方的文字框内输入对这次提交内容的说明,编辑好后点击右下角的“提交”按钮,等待提交完成即可。

提交内容的说明是很重要的,因为Git可以记录提交的时间,提交者和内容,但并不能自动记录提交的原因,因此这部分必须要认真如实填写,方便后续的维护。

每一次的“提交”操作都相当于是创建了一个版本,也就是添加了一条版本管理的历史记录。像刚刚这样重复操作,我们就可以记录下操作的历史。

想撤回某些文件的暂存时,只需要按住Ctrl键,在“已暂存文件”一栏下选择需要取消的文件,然后点击“取消选定暂存”即可。如果用刚刚什锦烧的例子说明,取消暂存就相当于是把原料碗从摄影台拿下来,等原料调好了再放上去拍照。

对于想要分开提交多个文件,或者没有提交时想要有所变更的情况下,都需要用到暂存区域。

4.用checkout移动提交

继续刚刚什锦烧的例子。我们做什锦烧需要的原料有:什锦烧粉,鸡蛋,卷心菜等等。现在我们按照以下的顺序,把每个放入原料的过程拍了照:

(1)放入什锦烧粉,水和鸡蛋;

(2)放入卷心菜;

(3)放入可乐。

等等……可乐好像放错了。不过没关系,我们已经给每个状态拍了一张照,我们只需要找到放入可乐之前的状态,按照这个状态回溯到对应的时间点就可以了。

在Git中,利用 checkout可以将文件更改为某个指定的版本。就像刚刚拍照片一样,找到对应的文件版本,我们就可以进行操作了。

在SourceTree中的操作如下:

在左端的“History”选项卡,找到需要回溯的提交记录,双击后在弹出的确认对话框中点击“确定”即可。

就算是移动到了过去的提交,最新的提交记录也还是存在的,使用的方法类似。

你可能注意到了,每一个提交都有一个对应的字符串,比如 b57e271430990131a7c0dae4c7e14aaee4b804c0。这是根据每一次提交生成的识别码,每一个提交都有一个独一无二的识别码。通过这串识别码,我们就可以辨别出来是哪个提交了。

为什么不用001,002这样的数字来作为识别码呢?如果在同一时刻两个人提交了操作,那么就没法分辨是谁修改的了。使用这样的40位识别码,就可以有效避免这个问题。

三、多人协作使用Git

Git的一大优势就是在于它是分散式的分布管理系统。集中式的分布管理系统由操作者共同使用一个仓库,使用的时候必须联网。而分散式的分布管理系统中,对于一个仓库,每位开发者都可以在本地保存仓库内容,在适当的时刻提交到中央仓库就可以了。

分散式管理系统有以下优点:

  • 就算是离线状态,也可以正常工作
  • 可以在不影响主仓库的条件下,自己修改代码调试
  • 紧急情况下,可以很快从别人的仓库进行复原

因此,Git更适合多人协作使用,在这一节中我们做较为详细的介绍。

1.创建Github账号

我们前面已经提到过,Github是常用的托管服务。在Github中,可以免费创建仓库用于代码托管。

打开GitHub,点击右上角的 Sign Up,按照指引进行注册。注册时需要准备一个可以使用的邮箱账号。

最近Github强制开启了两步验证,可能还需要在手机上准备一个生成校验码的APP,这里推荐Microsoft Authenticator或Google Authenticator。

GitHub在国内访问较慢,如果上网姿势正确的话对访问会有帮助。

2.复制仓库

为了方便使用,我们把仓库先进行复制(Fork),复制到自己的账号内,然后再进行克隆(Clone) 操作,将仓库下载到本地。

复制的步骤

打开一个仓库(在这本书中以这个仓库作为例子),点开后点击右上角的“Fork”,然后在新页面中点击“Create Fork”,等待几秒钟后便可复制完成。如果你成功复制了仓库,那么仓库名最开始的部分会变成你的Github用户名。

SourceTree中,克隆的步骤

先在仓库页面,点击“Clone or download”,复制显示出来的网址。然后回到SourceTree,点击文件-克隆/新建,在“源路径/URL”一栏中填入刚刚得到的网址,最后点击“克隆”即可。

3.创建分支

在Git的官方解释中,分支的本质是指向提交对象的可变指针。

为了方便理解,对于分支做一些形象的说明。假设我们现在要做一份寿司,那我们可以把这个过程分成两条线,一条是准备寿司用的米饭,一条是准备做寿司用的生鱼片,准备两种原料的过程是互不冲突的,这就是分支的理念。通过分支,可以很方便地进行并行工作,同时也不会相互干扰。

那什么是指针呢?指针,简单而言,就是指向“当前”。比如在准备米饭的分支里,是这样的结构:

开始——禾苗——稻穗——米饭

那么指针就指向的是当前这个分支下最新的节点。在上面的例子中,指针指向的是“米饭”。

确认目前所在的分支

在SourceTree中,目前所在的分支,会在左侧的“分支”选项卡下以黑色的粗体标出。

在Github中,创建仓库时会自动创立一个名字叫 main的默认分支,就像是河流的干流。在早些创建的仓库上,默认分支名字是 master

分支的移动

利用 checkout命令,也可以进行分支的移动。比如,我们现在处于米分支,那么我们就可以通过 checkout,移动到鱼分支来对其进行操作。不仅如此,利用 checkout,还可以移动到分支下任意的一次提交。在SourceTree中,想要移动分支,只需要在左侧的“分支”选项卡下,双击需要移动到的分支即可。

创立分支并提交

在SourceTree上的操作步骤如下:

点击顶部菜单栏下方的“分支”,在“新分支”选项卡下输入分支的名字,点击“创建分支”按钮。

https://images.shojola.top/Create_branch_d41d8cd98f00b204e9800998ecf8427e.png

创建好并修改代码后,进行暂存和提交操作,即可完成对对应分支下的提交。

4.合并分支

我们已经创建了一个分支,当我们想把当前分支的更改合并(merge)到主分支里,又需要怎么做呢?

还是以寿司的例子讲解,我们现在已经准备好了米饭和鱼肉,现在我们打算把两个合并起来,做成寿司。我们需要先移动到米分支上,再读取鱼分支进行合并。简单来说,合并分支的操作就是:

1.切换到主分支;

2.读取需要合并的分支,进行操作。

在SourceTree中,合并分支的步骤如下:

1.双击 main(或 master)分支,切换到主分支;

2.右键需要合并的分支,点击“合并 xxx分支至当前分支(xxx是你需要合并的分支的名字)”,等待片刻后即可合并完毕。

什么时候需要合并分支呢?比如说,bug修复的分支已经完成了自己的任务,那么就可以把bug修复后的代码合并到主分支上。添加新功能时,也可以这样合并到主分支上。

冲突

在合并的时候有这样一种情况,当同一行代码在同一时间被不同的人修改时,Git这个时候就不知道应该合并哪个代码,这样的情况就叫“冲突”。

在SourceTree中,如果遇到冲突,提交的时候会遇到这样的提示:

https://images.shojola.top/Conflict_d41d8cd98f00b204e9800998ecf8427e.png

解决冲突

对于出现冲突的文件,SourceTree会对应地用感叹号标出来:

https://images.shojola.top/Conflict_Warning_d41d8cd98f00b204e9800998ecf8427e.png

打开对应的文件,可以看到Git已经标注出来了对应的冲突点:

https://images.shojola.top/Conflict_in_File_d41d8cd98f00b204e9800998ecf8427e.png

修改冲突的地方后,再次进行暂存和提交即可。

修改冲突后进行提交,SourceTree会自动生成解决冲突的提交注释,当然也可以根据需要自己修改提交注释。

5.推送

刚刚我们对分支的操作,都还在本地上,我们需要通过推送(push),来把代码推送到远程仓库。还记得在第二节我们复制了一个仓库吗?这个就是我们要推送代码过去的目标仓库。

在SourceTree中,想要推送代码的话,点击上方的“推送”按钮,在需要推送的分支前勾选“是否推送”的复选框,点击“推送”按钮即可。

推送过程中可能会弹出Github的登录窗口要求验证。

6.拉取

多人协作中,往往会出现我们需要获取其他编辑者的更改的情况,这个时候就需要用到拉取(pull)

假设他人已经提交了代码,但是我们还没有同步,那么在SourceTree中的操作如下:

点击最上方的“拉取”,在“要拉取的远端分支”一栏,确认拉取的分支是从主分支到主分支,核对好后点击“确定”,稍等片刻拉取就完毕了。检查提交记录,应该也可以看到对应的更改了。

7.拉取请求与合并

假设我们已经修改好了代码,想要把更改上传到主仓库,这时就需要用到拉取请求(pull requests)

明明是我们推送代码,为什么要写成是“拉取请求”而不是“推送请求”呢?其实这个说法是从对方的角度来说的,从对方来看,我们的需求是需要主仓库从我们的仓库“拉取”代码,因此是“‘拉取’请求”。

为什么我们不能直接把代码上传上去,还需要得到“允许”才可以呢?如果没有审核环节的话,上传的代码得不到检查,就很容易产生漏洞,或者是功能上的不匹配。而经过负责人的检查后,代码确保没有问题才会被合并,这样更不容易出问题。

简单来说,拉取请求与合并的步骤如下:

复刻->克隆->创建自己进行操作的分支,提交->推送->Github上生成拉取请求->被合并。

在SourceTree中的操作步骤如下:

1.按照我们之前的步骤,复制仓库,创建分支,编辑文件,然后进行提交和推送。

2.打开浏览器,来到我们复制的仓库主页。点击仓库名下的“branches”,弹出的页面会显示目前仓库下的所有分支。

3.在“Active branches”下找到想要进行拉取请求的分支,点击右边的“New pull requests”,确认需要合并的分支正确后,填写说明点击“Create pull request”提交请求。

这是提交拉取请求的步骤。如果是仓库管理者,需要进入“Pull request”选项卡查看拉取请求。确认无误后,点击“Merge pull request”即可完成合并。

当然,提交的请求也可能会被驳回。这个时候只需要在同一个分支上,按照注释修改代码,再提交和推送,就可以简单地更新拉取请求的内容了。

8.忽略无须进行版本管理的文件

在Git仓库中,有些文件是不需要进行版本管理的,比如系统自动生成的文件,缓存或者容量过大的文件等。在Git中,可以通过在仓库内建立名叫 .gitignore的文件,指定不需要版本管理的文件。

.gitignore文件的书写规则如下:

  • 备注:在这一行的开头加 #,例如:

    1
    # 这是一条备注,它大概有这么长
  • 忽略特定文件,输入对应的文件名即可:

    1
    2
    # 忽略名叫filename.txt的文件
    filename.txt
  • 忽略特定扩展名的文件:

    1
    2
    # 忽略扩展名为txt的文件
    *.txt
  • 不忽略某个文件:

    1
    2
    # 不忽略filename.txt
    !filename.txt
  • 忽略特定目录:

    1
    2
    # 忽略folder文件夹下的所有文件,对于仓库内所有叫folder的文件夹都有效
    folder/
  • 忽略根目录下的子目录内的文件:

    1
    2
    # 忽略根目录的folder子目录下的所有文件,仅对根目录符合要求的文件夹有效
    /folder/

更多的 .gitignore编写规则,可参考这个网站

在SourceTree中,向 .gitignore写入忽略规则的步骤如下:

(1)点击右上角的设置,在“仓库设置”对话框中点击“高级”选项卡,再点击“仓库指定忽略列表”中的“编辑”选项卡;

(2)弹出编辑界面,按照上述规则按需配置;

(3)保存,暂存并提交。

如果想要忽略已经提交的文件,在SourceTree中需要以下操作:

(1)在“文件状态”选项卡中,点击右侧上方的下拉选项卡,选择“所有文件”;

(2)在“未暂存文件”一栏中,选择想要停止追踪的文件,右键点击“停止追踪”;

(3)提交此次更改,随后向 .gitignore中写入忽略信息,再次提交。

9.如何高效使用分支

我们可以通过分支创建不同的工作流程,而正因如此,如何高效使用分支成为了一个课题。在这里介绍一种推荐的使用规则——GitHub Flow。你可以点击这里来了解相关的信息。

对于GitHub Flow,它的分支模型可以分为两部分:

(1)main分支:此分支上的代码需要保持随时可发布的状态,原则上不在此进行操作;

(2)topic分支:用于对项目的开发,比如增加新功能,修复程序错误等。开发完毕后,再向main分支发送拉取请求进行合并。topic分支的名字最好直观易懂。

GitHub Flow的使用规则如下:

(1)main分支必须任何时刻都可以公开发布;

(2)需要进行新功能开发时,需要新建分支,分支名字可以直接反映新功能;

(3)定期推送分支;

(4)如果想要获得反馈建议,或者已经开发完毕需要合并到主分支,就发送拉取请求;

(5)合并的代码必须经过审计后通过;

(6)合并分支后,可以直接发布。

遵守上述规则,只需要浏览分支就可以知道目前在进行什么开发了。而代码经过审计,也可以保证代码的质量和稳定性。

四、实用Git~这些时候,该怎么办呢?

1.回到过去,创建新分支,修改内容

依旧是设想一下做什锦烧的场景。我们已经现在有了三个时间点(提交):

(1)放入水,鸡蛋,什锦烧粉;

(2)放入卷心菜;

(3)放入鸡肉。

如果我们想要另外做一份猪肉什锦烧,就需要回到放入卷心菜这一步,更改配料进行制作。用Git的语言表述这个过程,就是想要从过去的某一次提交开始,新建分支进行开发。这时候应该怎么操作呢?我们只需要先移动到需要对应时间点的提交,然后从这里新建分支即可。

在SourceTree中的操作如下:

1.左侧点击“History”选项卡,双击想要返回到的提交,在弹出的对话框选择确定;

2.点击最上面的“分支”选项卡,在“新分支”选项卡下,填写新分支信息,创建分支;

3.创建完毕。在此状态下提交,就可以实现需要的效果了。

2.撤销过去的提交(revert

假设我们现在有这样一条提交记录:

A-B-C-D(D为最新提交)

那么是否可以撤销一个过去时间的提交(比如提交B)呢?这时候就需要用到revertrevert撤销的原理并不是简单粗暴地删除这次提交,而是通过提交一次与这次提交完全相反的内容来实现撤销更改的效果。

在SourceTree中,想要进行revert,只需要右键点击对应的提交,选择“回滚提交”即可。

当变更的内容与指定的内容在同一行时会产生冲突,使用前面介绍的方法解决冲突即可。

3.提交历史合并为一条直线(rebase

本节使用的图片来自知乎,你可以点击前面的蓝色字体进行访问。图片版权归原作者所有。

我们前面已经介绍了用merge合并分支。思考这样的分支:

对于两条分支,如果用merge进行合并,那么合并后会变成这样的结构:

可以看出来,使用merge合并,提交的历史记录依然保持在原先的分流状态。在这里我们介绍一种新的合并方式:rebase。如果使用rebase来进行合并,那么就会变成这样:

容易看出,rebase把之前的提交记录重新整理为了一条直线。在一些情况下,利用rebase进行操作,可以使提交记录更为清晰易懂。

rebase修改的只是提交记录。也就是说,对于同一个合并操作,使用两种方法合并后的代码是一致的。

但是,使用rebase也要小心,因为rebase会把所有的历史提交重新生成新的提交,在这之中提交的id值也会改变。如果把远程仓库已有的分支进行rebase,那么如果有的使用者想要提交新的代码,就会遇到很大的麻烦(因为提交记录不匹配)。所以,在熟练掌握rebase前,尽量先使用merge进行合并操作。

在Sourcetree中,想要进行rebase,只需要先双击移动要进行rebase的分支,然后在需要rebase的目标分支上,右键选择“将当前变更变基到xxx”即可(xxx是目标分支的分支名)。

如果在rebase的过程中发生冲突,先点击上方菜单栏中的“操作”按钮,选择“解决冲突”。按照之前介绍的方法解决冲突后,再选择“继续变基”,即可完成rebase的操作。

4.合并多个提交(squash

当对一个地方修改很多次后,提交历史会变得比较繁琐,如果能把对这一个地方的提交合并在一起进行记录,就会变得简洁很多了。这个时候就可以用到squash

要注意的是,由于squash的操作会改变提交记录,所以必须确认需要合并的提交记录只在本地。合并已经在远程仓库的提交记录容易造成混乱。

squash有“压缩,挤压”的意思,这样想可以方便理解一些。

在Sourcetree中的操作方法如下:

1.先确认需要合并的多个提交记录,找到在这群提交记录之前离得最近的一个提交记录,右键选择“交互式变基commit id的子提交”(commit id是进行右键操作的对应提交的id);

2.在弹出窗口勾选想要进行合并的提交,点击“用此前的squash”按钮,然后点击“编辑信息”按钮,修改提交注释,全部完成后,点击“确定”进行提交,合并完成。

如果编辑过程中出现混乱,可以点击“重置”按钮从头开始操作。

squash中解决冲突的操作与rebase相同,这里不再赘述。

5.拉取是怎么实现的? 获取远程仓库的最新状态(fetch

我们前面已经介绍了通过拉取功能来同步本地仓库与远程仓库的提交,现在我们来详细解释一下这个过程。

到目前为止,我们认为的拉取操作是这样的:

远程分支->本地分支

但其实这个过程是这样的:

远程分支->远程跟踪分支->本地分支

我们注意到,中间其实是有一个叫做“远程本地分支”的本地仓库充当“中介”的角色。远程跟踪分支是远程分支在本地的镜像,它是处于只读状态的。

我们把“远程分支->远程跟踪分支”的这个过程叫做fetch。由此我们可以得出,拉取(pull)的实现,其实是同步(fetch)与合并(merge)两个过程的结合。

如果再详细介绍一下上述过程,那么就应该是这样的:

在一般情况下,三个仓库的进度是相同的。现在,远程仓库多出了一个提交记录,那么Git会先把这个提交记录同步到远程跟踪分支上,也就是fetch。这个时候,远程的提交记录暂时还没有合并到我们的本地仓库上,我们目前只是知道了远程仓库多出来了一条这样的提交。如果我们确认要把这个提交合并到本地仓库,那么再使用merge。如果是拉取的话,那么两个过程就是先后同时进行的。

简单来说,拉取的命令并不是简单地把提交直接同步到本地仓库上,而是先把提交同步到一个跟踪远程分支的本地仓库里,再把提交同步到我们本地的工作仓库上。如果我们只是想要查看远程代码的开发进度,而暂时不想进行合并,那么就可以使用fetch命令进行操作。

想要在Sourcetree中使用fetch,只需要点击上方的“获取”按钮,再点击“确定”即可。如果想要进行合并,只需要在最新的提交上右键,点击“合并”即可。

6.删除不需要的远程分支

对于已经合并的分支,可以直接删除,提高使用效率。

一定要认真考虑整个团队的开发进度和运营方式后再决定是否要删除分支!

在Sourcetree中,想要删除分支的步骤如下:

(1)打开左侧菜单栏的“远程”选项卡,点开“origin”,在其下方找到需要删除的分支,点击删除“origin/分支名”,在弹出后的提示框确认,此时完成了远程跟踪分支下的分支删除。推送之后,远程仓库的分支也会被删除。

(2)在左侧的“分支”选项卡下,进行同样的操作。此时完成对本地仓库的分支删除。

如果其他成员在远程仓库删除了分支,我们也想删除对应的分支时,需要先点击“获取”,在新的对话框中取消勾选“删掉所有远端现已不存在的跟踪分支(tracking)“,然后点击确定,先将更改反映到远程跟踪分支上。此后再按照前面的介绍,删除本地的对应分支就可以了。

如果直接右击“远端”选项卡下的“origin”,然后再点击“删除origin”,这样会直接删除掉整个远程仓库!除非你知道你在干什么,否则一定不要这样做!

7.修改最近的提交注释(amend

如果注释中出现错误已经提交,但是还没有推送到远程仓库的时候,可以进行修改。修改仅限于最近的一次提交。

在Sourcetree中的修改方法如下:

在编写注释信息的文本框上方,点击“提交选项”的下拉框,选择“修改最后一次提交”,弹出对话框确认,修改之后再提交即可。

8.暂存未提交的内容(stash

如果正在编辑某个内容,而此时又需要放下现在的工作去修复另外的问题,这个时候就可以用stash,将现在的工作内容暂存起来,等到之后再取出来继续工作。

在Sourcetree中,想要进行stash,只需要先在提交记录中选择“未提交的更改”,在弹出的对话框中取好名字,确认即可。想要恢复的话,需要点击左侧的“贮藏”按钮,右键下方刚刚贮藏的内容,点击“应用贮藏区……”,确认即可。

9.从其他分支上获取特定提交(cherry-pick

如果在进行提交时搞错了分支,这个时候可以使用cherry-pick解决。它可以把任意的提交复制到当前分支。

“cherry-pick”是一句英文俚语,意思是“只挑熟的樱桃摘取”。考虑一个这样的分支:

main: A-B-D-E

vice: A-C

利用cherry-pick,可以把主分支的提交E移动到vice分支上,也就是变成这样:

vice: A-C-E’

要特别指出的是,cherry-pick的作用只是“复制”而不是“移动”,原提交依然在对应分支上。

在Sourcetree上,进行cherry-pick,只需要先移动到想要进行新增提交的分支,然后右键想要获取的提交,选择“遴选”,在弹出的确认框中确认即可。

10.错误地把HEAD直接指向了某次提交

我们先来解释一下什么是HEAD。在Git中,HEAD是一个指针,它指向主分支的最新提交。但是有的时候,因为一些原因,我们可能会移动到了某次提交,这个时候HEAD就指向了某一次提交,HEAD就和主分支分离开了,这就是detached head。在这种情况下,我们可以进行提交,但是此时的提交是不属于任何分支的(因为这次的提交已经和主分支分离开了,并不会保存到主分支上),如果我们再次移动到主分支,这些提交就会丢失。

对于detached head状态,想要解决也很简单,在刚刚的提交的基础上创建一个新分支就好了。当然,因为这种状态下,提交不会被保存,所以也可以在这种状态下进行一些实验性操作。

11.在Github Pages上发布网页

在Github上,如果仓库放的是网页源文件,可以很方便地通过Github进行网页的发布,并且不需要服务器。操作的步骤如下:

(1)打开需要发布的仓库的页面,点击上方的Settings

(2)在左侧选择Pages,随后Source选择Deploy from a branch,下方的Branch选择想要发布页面的分支,然后点击Save

(3)输入网址(https://username.github.io/repository,其中`username`是用户的Github用户名,`repository`是发布网站的仓库名字),即可访问。