目录
一、Git是什么,GitHub、Gitee、GitLab又是什么?
二、Git的使用
2.1 Git的下载与安装
编辑2.2 使用Git前不得不知道的理论知识
2.2.1 Git的工作区域
编辑2.2.2 Git的工作流程
2.3 Git的落地使用-命令的使用
2.3.1 先熟悉Git的一些基本常用命令
2.3.2 实操一:Git基本操作
2.3.3 理解Git的分支概念
2.3.4 Git分支操作相关命令
2.3.5 实操二:Git分支操作
我相信很多人在为学习过Git之前,即使Git可能不知道,但GitHub应该都听过,或多或少的听到别人说可以使用它来进行学习,可以方便的查找别人的代码,并可以进行代码的拉取,可能也只是单单的知道,具体如何操作可能还并不知道,好,下面我将逐个介绍它们,让你明白它们到底是什么,到底是用来干嘛的,首先,Git应该是最先引出来的,后面的GitHub、Gitee以及GitLab都是以Git为基础的,通常需要配合Git进行使用,那Git到底是什么呢?其实一句话就够了,就是一个版本控制工具,听到这个你可能大概就知道是个什么东西了,版本控制工具?版本控制?那不就是大概就是一个可以记录版本的工具吧,不然怎么叫版本控制呢,此外你可能还想,既然是控制,那么应该可以灵活的对版本进行修改,是的,到这里你的理解是没一点问题的,接下来你可能还会想,在我们平常使用电脑进行版本的管理,很容易就是直接先保存一份,然后在进行修改,就如下图所示:
既然说可以这样简单的实现,那为什么还要有Git呢?换言之,Git相较于这种又会有什么特别之处呢?有什么特别的功能呢?其实当初我学的时候也没有仔细思考过这个问题,没有仔细比较过它两就直接学Git了,其实还是得了解一下到底为什么要产生Git,到底是具备哪些优点?这可以加深对Git的理解,下图是我问ChatGPT它给出的答案:
确实仔细看看它说的确实还挺对的。相较于原来的传统方式,空间效率提高了,便于协作开发了,最重要的是,Git创新地提出了分支的概念,使得可以并行进行开发,互不干扰,最后还能将不同分支的工作进行整合,另外还能自动的知道冲突在哪,配合上IDEA的使用,能很方便的来手动解决冲突。
知道了Git是个什么玩意了,那GitHub、Gitee、GitLab又是什么呢?其实啊,它们进行版本控制的,但Git是将版本信息存储到本地,是一个本地版本库,而GitHub、Gitee、GitLab它们则是远程库,其实也就是一个代码托管中心,这样可以很方便的将本地代码上传上去,以及将远程库中代码拉取到本地,这样便于代码共享,成员可以将代码荡下来,然后进行修改,然后提交到远程库,也就是更新远程库中代码版本,就可以通过这种方式,进行协同开发,很是方便。
那除了Git这种版本控制工具之外,还有没有其他的版本控制工具呢,相较于其它的版本控制工具又有哪些区别呢?下面是ChatGPT给出的答案:
和经典的SVN这种集中式版本工具进行对比的话:
下面的图很好的描述集中式版本控制与分布式版本控制的区别:
集中式:
分布式:
最显著的区别就是,一个是分布式,一个是集中式,分布式可以很方便使得用户在自己的本地进行操作,也就是可以进行离线操作,各干个的,分布开来了,因而称作分布式,另外也不依赖于中央服务器,操作都可以在本地进行离线操作,对网络的依赖低,效率更高。
Git作为一个软件,要想使用它,当然第一步就得先下载它:
下载地址:Git - Downloads (git-scm.com)
当然这里不一定得安装Windows版的,也可以选择MacOS和Linux版,根据自己的需求灵活选择。
选择好后,进行下载即可。
安装:
1. 查看 GNU 协议,可以直接点击下一步查看 GNU 协议,可以直接点击下一步
2. 选择 Git 安装位置,要求是非中文并且没有空格的目录,然后下一步
3. Git 选项配置,推荐默认设置,然后下一步
4. Git 安装目录名,不用修改,直接点击下一步
5. Git 的默认编辑器,建议使用默认的 Vim 编辑器,然后点击下一步
6. 默认分支名设置,选择让 Git 决定,分支名默认为 master,下一步
7. 修改 Git 的环境变量,选第一个,不修改环境变量,只在 Git Bash 里使用 Git
8. 选择后台客户端连接协议,选默认值 OpenSSL,然后下一步
9. 配置 Git 文件的行末换行符,Windows 使用 CRLF,Linux 使用 LF,选择第一个自动 转换,然后继续下一步
10. 选择 Git 终端类型,选择默认的 Git Bash 终端,然后继续下一步
11. 选择 Git pull 合并的模式,选择默认,然后下一步
12. 选择 Git 的凭据管理器,选择默认的跨平台的凭据管理器,然后下一步
13. 其他配置,选择默认设置,然后下一步
14. 实验室功能,技术还不成熟,有已知的 bug,不要勾选,然后点击右下角的 Install 按钮,开始安装 Git
右键任意位置,在右键菜单里选择 Git Bash Here 即可打开 Git Bash 命令行终端
在 Git Bash 终端里输入 git --version 查看 git 版本,如图所示,说明 Git 安装成功
Git的工作区域分为工作目录、暂存区域以及本地仓库三个;
使用下图进行理解:
于是乎,对于着三种状态:已修改(modified)或者是新增的未被跟踪其实都是未被跟踪,已暂存(staged),已提交(committed)
git config --global user.name 用户名 | 设置用户签名 |
git config --global user.email 邮箱 | 设置用户签名 |
git config -l | 查看Git配置 |
git init | 初始化本地库 |
git status | 查询本地库状态 |
git add 文件名 | 将文件提交到暂存区 |
git commit -m 提交信息 文件名 | 将文件提交到本地库 |
git reflog | 查看历史记录(简洁版) |
git log | 查看历史记录(包含时间,修改人等信息) |
git reset --hard | 回退到指定版本 |
补充命令:
git restore 文件名 | 撤销修改或删除操作(对已经提交到本地库中的文件),重新回到工作目录 |
git config --global user.name 用户名
可以设置用户名
git config --global user.email 邮箱
设置用户的邮箱(注意:可以不是真正的邮箱,完完全全只是一个标识,没有什么特别的意义,与GitHub登录的邮箱没有任何关系)
其实设置其它全局属性也可以使用git config --global 参数名 参数值的方式进行设置,比如说默认分支等。
git config -l
查看当前git的参数信息
git init
初始化本地库
git status
查询本地库状态
git add 文件名
将文件提交到暂存区
git commit -m 提交信息 文件名
将文件提交到本地库区
git reflog
查询日志信息,可以获取操作记录,比如说提交信息,日志信息较为简略
git log
查询信息的日志信息
git reset --head 版本号
可以回退到指定版本
分支作为Git相较于普通的文本副本方式进行版本控制而言是创新的存在,其实分支就可以理解在当前头指针的位置创建"副本",然后可以对这个"副本"进行操作,然后"副本"是单独的存在,可以进行对其进行单独的开发,与"原本"互不干扰。其创建分支的操作,有以下动作:以当前头指针位置创建一个"副本",此"副本"与头指针执行的文件内容相同,然后同时将头指针移动到当前新创建的分支的新版本上面。这样就可以离开主线进行开发,创建分支进行开发,当分支开发完后,可以合并到主分支上面,使其对主分支进行更新。在SVN中创建分支其实就是复制目录,分支操作较慢,而Git相较于SVN创建、删除、合并分支更容易,切换分支的速度更快,使得团队更好的进行并行开发和特性分支的管理。当然由于Git是分布式的,开发者可以轻松的进行并行开发,这也加大了冲突的可能性。怎么合理的解决冲突也是一个问题?下文中我会着重介绍冲突这部分内容。
分支可以通过下图描述:
git branch -v | 查看本地分支 |
git branch 分支名 | 创建分支 |
git branch -D 分支名 | 强制直接删除本地分支,不检查 |
git push 远程链接 -d 分支名 | 删除远程分支 |
git remote prune 远程链接 | 清理远程已删除,但本地还显示存在的远程分支 |
git branch -d 分支名 | 删除本地分支 |
git branch -a | 查看远程分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名 | 将分支合并到当前分支 |
git branch -v
显示分支,其中*表示当前分支
git branch 分支名
创建本地分支
git branch -D 分支名
强制删除本地分支
git checkout 分支名
切换分支
git merge 分支名
合并分支
分支是为了开发方便,并行的开发,最终肯定还是要合成一份的,形成一个全新的版本,合并时是需要讲究规则的,不能乱合并,其实规则就是“尽可能的保留修改,舍弃原来的,以使得这个版本尽可能的做了较多的修改,尽可能的新”,这句话怎么理解呢?就是对于两个分支,如果同时操作了两个文件,同时修改了两个文件,首先要知道这两个分支其实是有一个起始分支的,起始分支其实就可以看作是被合并的那个分支,然后合并两个分支,最终保留的是两个分支修改的部分,当然在遵循这个原则的情况下,有个时候如果两个分支都同时进行修改了,那又怎么作抉择呢?Git是不知道到底该保留哪一份的,因为都进行修改了,按照规则,保留修改的部分,可是都修改了都属于是修改的部分,那我到底应该保存哪个修改的部分呢?Git是搞不清的,需要我们来进行手动合并,也就是产生了冲突问题。就比如我举下面这个例子:
分支A:
World
Hello
分支A经修改后:
Hello World
Hello
分支B:
World
Two
现在将B分支合并到A分支上的结果为:
Hello World
Two
解释:就是A分支修改了第一行就保存下来,B分支修改了第二行也保存下来,于是就产生了最后的这个结果,其实就是保留了各个分支的修改,注意,这里是保留修改,而并不是单纯的"取两部分交集",保留的是修改后的,原本的不需要保留,只是说如果两个分支都没有进行修改的话,那么其实也可以看作是修改了,只不过这个修改是没修改罢了,可以看作时"改变系数"为0的"特殊修改"。
当然现在这种合并是没有问题的,可以正常的进行合并,我只要把上面的例子,简单的换一下,就会产生冲突问题了,冲突就一个,就是两个分支相较于"起始分支"对同一行都进行修改的话,就会产生冲突了。就比如说改成下面这样:
分支A:
World
Hello
分支A经修改后:
Hello World
Hello
分支B:
One World
Two
现在这样就会出现合并冲突了,因为两个分支相较于"起始分支",都对第一行做了修改,那么原则是保留修改,可是到底应该保留哪个修改呢?Git懵了,需要我们手动的解决冲突,进行分支合并,虽然Git不能直接进行合并,但是Git能在最后给予给我们一份“新的文件”,里面有着两个分支的修改。就比如说上面的那个例子,最终可以产生下面这样的结果:
<<<<<<< HEAD
Hello World
Hello
=======
One World
Two
>>>>>>> branchB
<<<<<<< HEAD到=======之间就是当前分支修改之后的整体样子(也就是A分支最终的样子),而=======到>>>>>>> branchB就是被合并分支修改之后的整体样子(也就是B分支最终的样子)。
解决冲突的办法:就是手动修改最终Git给我们的"合并之后的"文件,然后将文件重新add 以及重新commit 即可,但是这里commit不需要再给出文件名了。就比如说上面那个例子,就可以把最好的文件修改成下面这个样子:
Hello World,One World
Two
然后git add 文件名,最后git commit -m "提交消息" 然后就能以合并后的一个全新的版本保存在本地库中了。
下面给出实操例子
没有冲突的合并:
另外强有力的证明我的论点:也是一个没有冲突的合并
就是两个分支相较于"起始分支"对同一行都进行修改的话,就会产生冲突了,而并不是说只要先后两个分支对文件进行修改的话,就会产生冲突这一论点其实是错误的,也就是说尚硅谷的老师的git教程再进这个冲突的时候,说这个冲突的条件其实是不严谨的,说的有点大了,下面我这个例子进行了强有力的证明了我的论点为什么正确:
合并后两个分支在对文件分别进行修改:
因为上面那个例子已经是master和hot-fix两个分支已经合并了,就可以看成当前又变成只有一个master分支时的情形了,所以这里为了测试有冲突的合并,肯定还得是两个分支分别对文件同一行都进行了修改才行体现出,而现在就只有一个最终合并之后的分支,显然是不能进行演示的,因此这里我还得另外在创建一个分支,其实上面的例子就如下图所示的情形:
下面是Git标记的冲突: