前言
在日常工作中,有的同学已经在使用git了,有的可能刚开始使用git,有的是使用一些可视化的工具,那今天我带大家来认识一下git的原生态,命令行式的git操作。
版本控制系统
我想在讲git之前,有必要先了解一下什么是版本控制,什么是版本控制? 版本控制是一种记录一个或若干文件内容变化,一边将来查阅特定版本修订的系统。 就在前段时间,我们要写年度总结报告,你写了很多,想删除一部分,又想着删了可以啊,明年可以再继续留着用啊,那你会怎么做,先把当前这个另存为一份,但你写着写着又写嗨了,再另存一份,就这样改着你的年度总结报告成了这个样子。
时光荏苒,又到了新的一年,你想把去年的那段内容拿出来用,已经记不清楚放哪里了,只能一个文件一个文件去翻找,那这个就是咱们一种本地版本控制系统,这时候你在想,如果能有个系统帮我们记录这些还能在不同系统上的开发者协同工作就好了,于是集中式的版本控制系统应运而生啊。
集中式版本控制系统
集中式版本控制系统,它的版本库是集中存放在一个中央服务器的,而每个客户端要干活的时候,需要从这个中央服务器获取最新的版本,然后开始干自己的工作,最后再把自己干的工作推送到给中央服务器。也就是说只要是所有项目成员共同存取在同一个仓库,那这种方式就是集中式版本控制系统,它的代表是SVN也就是这个小乌龟。 那集中式版的显而易见的缺点就是这个中央服务器的单点故障,如果宕机一个钟头,那么这一个小时谁也无法提交更新,也就无法协同工作了。 如果哪天这个服务器的磁盘发生损坏,恰好你又没备份,那就偶买噶,你会丢失所有的数据,包括整个的变更历史,只剩下各自客户端上保留的单独的快照了。 于是,分布式版本控制系统诞生了。
分布式版本控制系统
分布式版本控制系统的特点在于分布,每个客户端都可以在自己的电脑上建立仓库,并不是只提取最新版本的文件快照,而是把一个项目的完整的镜像下来,这里面包括完成的历史记录,这样一来,如果协同工作的服务器发生故障,就可以用任何一个镜像出来的本地仓库进行恢复。
分布式的版本控制系统通常呢也会有一个充当“中央服务器”的计算机,例如一些进行代码托管的github,gitlab,gitee等等,大家都把版本推送到这台计算机上,而需要同步的人只需同步这一台固定的计算机就行了。说到这里,你可能觉得怎么说半天又绕到集中式版本管理系统了,其实不是的,分布式的版本控制系统中这个“中央服务器”只是一个充当中介作用的,每台客户端通过这个固定的中介交换意见后,都会拥有一个完成的版本库。分布式版本控制有很多,今天咱们讲讲其中的一个git。
git的诞生
这个人我不知道大家认不认识,他叫李纳斯,在1991年时候创建了Linux,到目前为止Linux已经成为世界最受欢迎的服务器操作软件了,当然linux的壮大也不是老李一个人的功劳,是由全世界的志愿者共同参与的,那老李是如何管理linux的代码呢?在2002年之前,都是志愿者通过各种途径发送给他,由他手动方式进行合并,那也有一些免费的版本控制系统,像svn啥的,后来我跟老李打电话问了一句,他说svn系统速度慢还要联网不好用,那还有一些商用的好用的分布式控制系统呢,他说妈耶收费的啊,你觉得跟我们Linux开源(baipiao)精神符合吗?
到了2002年以后,linux发展已经10年了,代码量的巨大让老李吃不消了,于是有家公司叫Bitmover,这家公司CEO跟老李是好基友啊,于是就睡服说服老李选择他们公司旗下的商用的分布式版本控制系统Bitkeeper,可以授权Linux社区免费使用,但是呢,对许可限制了很多的条件,这就让Linux社区的很多大佬不满,于是3年之后,终于有人憋不住了,开始对Bitkeeper进行破解,然后就被发现了,于是Bitkeeper就收回了免费使用权。本来老李可以低头认个错,然后让社区的人遵守人家的规矩,但是他并没有这么做,在两周之后,老李用C写了一个分布式的版本控制系统,于是git 诞生了,在这特别感谢澳大利亚的这哥们,要不是他估计咱们现在也不会有这么好用的开源的分布式版本控制系统了。
下载安装
git的下载地址 git-scm.com/
有的时候可能打开特别慢可以用淘宝镜像:npmmirror.com/mirrors/git…
找到自己对应的系统下载安装即可。
检测安装
自报家门
工作流程
git有4个工作区域
工作目录(Working Directory):工作区,就是你平时存放项目代码的地方
暂存区(Index/State):暂存区,用于临时存放你的改动
资源库(Repository):本地仓库,就是安全存放数据的位置,这里面有你提交的所有版本的数据
远程仓库(Remote): 远程仓库,托管代码的服务器,可以简单的认为是你项目中的一台电脑用于远程数据交换
基本操作
把这张图看懂了,git基本上你就差不多会了。 手动五角星☆
创建仓库
文件忽略
这是一个 .gitignore 文件,在这个里面设置过滤规则,可以使文件忽略,不被push进仓库。 这里有一个小插曲,跟同事协同开发,结果可能我误删了这个文件,结果导致 依赖包被上传到远程仓库,结果他拉下来依赖不能用,每次都是删了,重新下载依赖,后来发现这个.gitignore文件没了。
文件状态
你的工作目录下的每一个文件都不外乎两大类状态: 已跟踪 或 未跟踪
未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制。
已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后, 它们的状态可能是未修改,已修改或已放入暂存区。简而言之,已跟踪的文件就是 Git 已经知道的文件。
编辑过某些文件之后,由于自上次提交后你对它们做了修改,Git 将它们标记为已修改文件。 在工作时,你可以选择性地将这些修改过的文件放入暂存区,然后提交所有已暂存的修改,如此反复。
git status 查看当前文件状态
git diff 比较文件不同,比较暂存区与工作区的差异
git add . 文件暂存
执行git add xyd.text,将文件加入到暂存区,暂存区多了一个新文件。可以看到git restore – 这个命令什么意思,就是把这个文件撤出了,将暂存状态变为未跟踪状态。
接下来我把项目中的hanke.text 做修改,使用status,可以看到文件是已修改状态, 如果没加入暂存区之前,可以看到git restore,是将工作区已修改的文件撤销到未修改状态,那我们接下来使用git add .把这两个文件都进行暂存。
假设此时,你想要在 hanke.text里再加条注释。 重新编辑存盘后,准备好提交。 不过且慢,再运行 git status 看看:
怎么回事? 现在 hanke.text文件同时出现在暂存区和非暂存区。 这怎么可能呢? 好吧,实际上 Git 只不过暂存了你运行 git add 命令时的版本。 如果你现在提交,hanke.text的版本是你最后一次运行 git add 命令时的那个版本,而不是你运行 git commit 时,在工作目录中的当前版本。 所以,运行了 git add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来:
git commit 将本地暂存的修改提交到版本库 git commit -m ”本次提交的说明“
git commit 命令用来将本地暂存的修改提交到版本库。我们用的比较多的应该就是-m 参数。添加提交信息
经常手抖的同事可能会知道,git commit 会出来一个这个界面,那这也是可以提交暂存的,只不过输入提交信息的时候是通过调用一个编辑器进行信息编写的。
那到这一步,咱们就完成了把文件提交到版本库了。
git log 查看提交历史
git log 有许多选项可以帮助你搜寻你所要找的提交, 下面我们会介绍几个最常用的选项。
其中一个比较有用的选项是 -p 或 --patch ,它会显示每次提交所引入的差异(按 补丁 的格式输出)。 你也可以限制显示的日志条目数量,例如使用 -2 选项来只显示最近的两次提交:
git reset 版本回退
git log命令可以让我们看到提交的历史,那Git允许我们在版本的历史和未来之间进行穿梭移动,我们还可以回退到指定的版本
git reset --hard 版本号: 回退到该版本号对应的版本
咱们git log,找到要回退的版本的版本号,最后是大于5位,这样就可以回退到第一次提交版本。咱们再使用git log,你会发现怎么就只有一个提交信息了,没错,git log 只会显示你当前版本之前的一些历史记录。那如果我想回到最新的版本怎么办?
git reflog 查看所有分支的所有操作记录信息
Git reflog 包括被删除的 commit 记录和 reset 的操作记录,如果你想再回到最新版本,可以找到最新的那次提交版本号,进行回退。咱们可以看到现在就回到了最新的版本了。
git log 和 git reflog* 的最大区别是能不能查询到被删除的* commit 记录和 reset 的操作记录,* log不能,而**reflog可以;所以以后要买后悔药就去找**reflog***。**
远程仓库的使用
git remote 查看远程仓库
远程仓库就是咱们之前说的那个类似于中介的一个托管在网络中的你的项目的版本库。如果想查看项目已经配置的远程仓库服务器,可以运行 git remote 命令。 它会列出你指定的每一个远程服务器的简写。当然它还有一个 –v 参数,列出简写与其对应的 URL。
创建远程仓库 例如: 码云
推送本地仓库到远程仓库
推送成功后,可以立刻在码云页面中看到远程库的内容已经和本地一模一样
git 分支
那我们已经知道,每次commit,都会生成一个节点,多个节点链接起来就好像一条时间线,那目前我们只有一条时间线,这个就叫主分支,即master分支。
分支在实际中有什么用呢?比如说,需要向项目中添加一个新功能,一般的团队都不会直接在主分支上修改,都会新建一个分支,在上面更改代码。这样做的好处就是保证主线代码的完整性和可用性,也就是说,主线上都是稳定的代码,可以直接拿来发布的。
分支管理 git branch
Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!
那接下来咱们在开发分支写了一个功能,并且提交到仓库,这个时候咱们时间线就会变成这样,咱们再切回到master 分支,可以看到master分支还是原来的样子,如何把这个新功能添加到咱们的主分支。通过下面这个命令
git merge 分支名 合并分支
咱们把分支切换到主分支之后使用 git merge 分支名,就可以进行分支合并,那有时候如何这个新功能涉及到了公共代码,就出现了代码冲突,这个是不会自动合并的,需要进行手动解决冲突,向左的箭头是保存当前,向右是保存插入的新代码。解决完冲突之后,提交仓库后,咱们可以看到这个新功能已经添加到master主分支了。
删除分支 git branch -d < name>
标签管理 git tag
像咱们目录链这个项目,之前可能有一期二期,这样就可以在一期最后提交节点分支上打上标签,这样就可以很快的标识到1期的节点,将来要给1.0版本做修改,咱们就不用再去git log 整个的提交历史中找commit的提交信息,直接找这个标签就可以了。 下面看下如何列出已有的标签、如何创建和删除新的标签、以及不同类型的标签分别是什么。