文章目录
- 为什么要学习Git
- 为什么要学习Git软件
- 为什么要学习Git软件
- Git基础概念
- 版本控制
- 集中式、分布式版本控制的区别
- Git工作区域
- Git分支
- 版本号
- 什么是版本号
- 文件操作对应的版本号
- 分支操作对应的原理
- 命令行操作
- Git相关配置的指令
- 获取当前Git的配置信息
- 名称和邮箱
- Git文件操作相关指令
- 初始化版本库
- 向版本库添加,修改、删除文件
- 查看版本库文件历史
- 恢复文件
- Git分支
- 主干分支
- 其他分支
- Git合并
- Git冲突
- 远程仓库拉取
- 通过HTTPS路径拉取
- 通过SSH路径拉取
为什么要学习Git
为什么要学习Git软件
- 为什么
学习
因为在主流开发中,基于互联网软件开发的项目都会使用Git软件来进行项目开发过程中的资源管理- 比如人力资源
- 代码资源 比如前端资源 .html .java等代码资源
- 文档资源 像项目开发中涉及到的需求文档等
这种项目中管理资源的软件被称为(软件配置管理)SCM软件
- 软件配置管理(SCM)是指通过执行版本控制、变更控制的规程,以及使用合适的配置管理软件,来保证所有配置项的完整性和可跟踪性。配置管理是对工作成果的一种有效保护。
- SCM(Software Configuration Management,软件配置管理)是一种标识、组织和控制修改的技术。它应用于整个软件生存周期。作为评价一个大中型软件开发过程是否正确,合理,有效的重要手段,
为什么要学习Git软件
- 那么多软件,为什么要学Git
常见的SCM软件
- 左边的软件都需要中央服务器,如果中央服务器损坏,那么项目的资源就会可能丢失,我们的Git就没这种问题
- Git软件比Subversion、CVS、Perforce和ClearCase等SCM(Software Configuration Management软件配置管理)工具具有性价比更高的本地分支、方便的暂存区域和多个工作
- Git免费开源
Git基础概念
Git是一个免费的,开源的分布式版本控制软件系统,学习Git软件的具体操作前,我们需要对一些基础的概念和名词进行解释
版本控制
什么是版本
-
软件版本
- 比如JDK1.8 JDK17 JDK20
- MYSQL5.7 MYSQL8.0
- IDEA2022 IDEA2023
- 这些数字都是软件的版本号
-
文件版本
-
保存重要的历史记录
-
能够实现恢复数据的功能
-
一般情况下,一份文件,无论是DOC办公文档,还是编程源码文件,我们都会对文件进行大量的修改和变更。但是我们无法保证每一次的修改和变更都是正确并有效的,往往有的时候需要追溯历史操作,而版本控制(Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。
-
版本控制的基础功能
- 保存和管理文件
- 提供客户端功能进行访问
- 提供不同版本文件的比对功能
没有进行版本控制或者版本控制本身缺乏正确的流程管理,在软件开发过程中将会引入很多问题,如软件代码的一致性、软件内容的冗余、软件过程的事物性、软件开发过程中的并发性、软件源代码的安全性,以及软件的整合等问题。
集中式、分布式版本控制的区别
集中式版本控制
- 多个用户同时改写了同一个文件,导致文件内容被覆盖,也就是文件冲突问题
- VSS解决方法 可以通过给文件加锁,限定用户进行修改来解决
- 比如用户1拿了一个文件,要进行修改,就给这个文件加锁,其他用户可以下载,但是不能修改,当用户1修改好了这个文件并上传,其他用户重新下载到本地,这时候才能进行修改文件
- 但是这样存在缺陷,不同的用户只能串行的进行修改文件
- CVS SVN的解决方法:一个文件的部分用来以一个用户的修改为准
- VSS解决方法 可以通过给文件加锁,限定用户进行修改来解决
分布式版本控制
Git工作区域
Git软件为了更方便地对文件进行版本控制,根据功能得不同划分了三个区域
- 存储区域:Git软件用于存储资源得区域。一般指得就是.git文件夹
- 工作区域:Git软件对外提供资源得区域,此区域可人工对资源进行处理。
- 暂存区:Git用于比对存储区域和工作区域得区域。Git根据对比得结果,可以对不同状态得文件执行操作。
- 我们的 git add 就是将工作区的文件加入到暂存区进行比较,而从暂存区加入到存储区是利用指令git commit
我们的本地仓库指的就是存储区域,我们commit就是将工作区的修改提交到我们的本地仓库,而我们的暂存区的作用就是对比工作区和存储区域的不同
Git分支
- 如果我们每个用户负责一个模块,直接提交给版本库带来的问题
- 历史提交记录中没有规律可言,非常乱
- 这样频繁的修改会导致大量的版本信息,会导致仓库更大
- 这样频繁的修改会引起大量的文件冲突
如果所有的操作都是基于一条主线完成的。就好比,咱们学习的时候,记学习笔记,今天学点,那么就写一点,明天学点,再写一点,最后,完全学完了,这个笔记也就记全了。但实际上,有些文件可能在不同的场合需要同时使用不同的内容,而且还不能冲突,比如项目的配置文件,我需要本地进行测试,同时还要部署到服务器上进行测试。本地和服务器上的环境是不一样的,所以同一个配置文件就需要根据环境的不同,进行不同的修改。本地环境没问题了,修改配置文件,提交到服务器上进行测试,如果测试有问题,再修改为本地环境,重新测试,没问题了,再修改为服务器配置,然后提交到服务器上进行测试。依次类推,形成迭代式开发测试。
从上面的描述上看,就会显得非常繁琐,而且本质上并没有太重要的内容,仅仅是因为环境上的变化,就需要重新修改,所以如果将本地测试环境和服务器测试环境区分开,分别进行文件版本维护,是不是就会显得更合理一些。这个操作,在Git软件中,我们称之为branch,分支。
这里的分支感觉上就是树上的分叉一样,会按照不同的路线生长下去。有可能以后不再相交,当然,也可能以后会不断地纠缠下去,都是有可能的。
引入分支之后
- 给我们的每个用户都分配一个备份的版本库,每个备份的版本库就是一个分支,我们经理的分支就是main
- 这里的分支原理,我们只是方便理解,其真正的实现并不是这样,在后面的版本号会详解解析
利用GithupDeskTop测试分支
主干分支
-
默认情况下,Git软件就存在分支的概念,而且就是一个分支,称之为master分支,也称之为主干分支。
-
这就意味着,所有文件的版本管理操作都是在master这一个分支路线上进行完成的。
-
不过奇怪的是,为什么之前的操作没有体现这个概念呢,那是因为,默认的所有操作本身就都是基于master分支完成的。而master主干分支在创建版本库时,也就是git init时默认就会创建。
其他分支
就像之前说的,如果仅仅是一个分支,在某些情况并不能满足实际的需求,那么就需要创建多个不同的分支。
Git合并
无论我们创建多少个分支,都是因为我们需要在不同的工作环境中进行工作,但是,最后都应该将所有的分支合在一起。形成一个整体。作为项目的最终结果。
版本号
什么是版本号
-
每次提交都会生成一个版本号,这个版本号是一个40位的16进制长度的数字字符串
-
为什么git软件产生的版本号这么长,git尝试的版本号是根据我们当前提交内容利用SHA-1加密算法得出,所以重复的概率很小
- 为什么需要保证重复的几率很小——Git是分布式版本控制软件系统,所以我们的版本库可能不止一个,而且会涉及到版本库的合并,所以我们的版本号重复会出现问题
- 根据版本号定位到仓库中的文件 2+38(前两位是文件夹,后38位的文件名)
- 在存储区中查找,也就是.git/objects
文件操作对应的版本号
这里的演示是连续的操作初始化—添加文件—修改文件—
初始化仓库对应版本号
- 一次初始化创建了两个文件.gitattributesh和README.md文件(可选),且创建了多个版本号,一个版本
添加一个文件对应版本号
- 我们的添加操作对应的提交信息中有指向上一次操作对应提交信息的文件 也就是对应parent的值
- 我们的文件状态文件会指向我们的新添加的a.txt。也会指向我们初始化操作添加的文件
修改文件对应的版本号
- 修改操作对应的版本的提交信息的文件中的parent指向上一次添加a.txt的操作的提交信息文件
- 对应版本的文件状态文件中会指向修改后的a.txt文件,也会指向我们初始化操作添加的文件
删除文件对应的版本信息
- 删除操作对应的版本的提交信息的文件中的parent指向上一次修改a.txt的操作的提交信息文件
- 对应删除操作的文件状态信息中只有指向初始化添加的文件,没有a.txt文件了
分支操作对应的原理
根据上面的图进行解释
认识两个文件
- 我们发现main文件下的内容就是我们上述操作中的最后一步操作,删除a.txt文件的提交信息文件的版本号
- HEAD就表示当前我们的分支是哪个,然后通过分支对应的文件指向对应的操作,来知道当前分支的操作最新操作是什么
我们添加一个分支并切换该分支
- 我们发现切换分支,我们的HEAD的文件中的内容就改变了
- 所以我们Git中就是通过heads文件下文件中内容指向不同版本的提交信息文件来实现分支的功能
命令行操作
Git软件是免费、开源的。最初Git软件是为辅助 Linux 内核开发的一套软件,所以在使用时,简单常用的linux系统操作指令是可以直接使用的
Git相关配置的指令
获取当前Git的配置信息
- 获取Git的配置信息: git config -l
作为一个工具软件来讲,一般都会有默认的配置文件来保存基础的配置信息,Git软件的配置文件位置为:Git安装路径/etc/gitconfig
名称和邮箱
如果你是第一回使用Git软件,需要告诉Git软件你的名称和邮箱,否则是无法将文件纳入到版本库中进行版本管理的。这是因为在多人协作时,不同的用户可能对同一个文件进行操作,所以Git软件必须区分不同用户的操作,区分的方式就是名称和邮箱。
当然了,你可能会说我就用本地库就行了,不需要进行多人协作,是不是就可以不用配置呢。这是不行的,因为Git软件的设计初衷本身就是针对于linux系统的分布式开发协同工作,所以它天生就是用于分布式协同工作的,这里无论你是否使用这个功能,它本身就是这么设计的。
- 设置用户名称:git config --global user.name 用户的名称
- 获取当前Git用户名称 git config user.name
- 设置用户邮箱:git config --global user.email 用户的邮箱
- 获取当前Git用户邮箱git config user.email
这里的–global表示全局配置,后续的所有文件操作都会使用该用户名称及邮箱。此时在操作系统的用户目录,会产生新的配置文件
Git文件操作相关指令
初始化版本库
Git软件主要用于管理文件的版本信息,但它只是一个软件,不可能安装后就直接将系统中所有的文件全部纳入到它的管理范畴中。并且,软件管理版本信息的主要目就是管理文件的修改和变更,如果将系统中所有文件都进行管理其实意义是不大的。所以一般情况下,我们需要指定某一个文件目录作为软件的管理目录。因为这个目录主要就作为Git软件的管理文件的版本变化信息,所以这个目录也称之为Git软件的版本仓库目录。
- 进入我们要管理的目录下,右击点击git bash here
- 输入git init
向版本库添加,修改、删除文件
- 因为文件已经放置在版本库中了。所以可以通过软件的指令查看版本库状态
- git status
此时会发现,test.txt文件属于untracked files(未追踪文件),这里表示当前的test.txt文件虽然放置到了版本库的文件目录中,被Git软件识别到了,但是未纳入到版本库管理中。所以属于未追踪文件。通过这个现象可以认为,系统文件夹物理目录和版本库管理目录的含义是不一样的。只有文件被纳入到版本库管理后,Git软件才能对文件修改后的不同版本内容进行追踪处理,也就是所谓的tracked files了
- 将文件test.txt交给版本库进行管理,也就是将我们工作区的文件放入我们的暂存区,与存储区域进行对比
- git add test.txt
此时文件状态为cached file,其实这也是Git管理文件时的一种状态:暂存状态。就是我们生活中常说的草稿状态。也就是说对于Git来讲,它认为此时文件只是一种临时草稿状态,随时可能会进行修改或删除,并不算真正的操作完成状态。所以并不会把文件纳入到版本库管理中。
-
将test.txt真正地纳入到版本库中
- git commit -m “新增一个文件”
- -m 表示提交时的信息(message),是必须输入的。用于描述不同版本之间的差别信息
查看版本库文件历史
版本库中的文件我们已经添加并提交了,那么文件的版本信息就会发生变化,那我们如何来查看这个变化呢?这里我们可以采用log指令进行查看
- git log
- 如果想美观一点,git log --pretty=oneline
- git log --oneline 简单查看
恢复文件
我们手动删除工作区的文件,并没有add和commit
此时Git软件会识别出来,版本库中有一份文件和当前用于临时操作文件的暂存区内的文件状态不一致:版本库中文件还在,但是操作区内的文件已经没有了。
- 所以软件提供了两个选择:
- 一个是将版本库中的文件也进行(提交)删除操作。
- git add test.txt
- 另外一个就是从版本库中恢复文件。
- git restore test.txt
- 一个是将版本库中的文件也进行(提交)删除操作。
如果想真的删除文件,需要将版本库中的文件也删除
版本库中的文件也被删除,如何恢复
如果版本库中一份文件中已经被删除了,那么此时这份文件还能找回来吗?其实原则上来讲,已经不行了,因为文件删除本身也是一种变更操作,也算是版本库管理的一部分。所以想要将已经删除的那份文件从版本库中取出来,已经是不可能了。但是,要注意的是,版本库管理的是文件不同版本的变更操作,这个不同版本的概念还是非常重要的。也就是说,最后的那个删除的文件版本已经没有了,但是之前版本的文件其实还是存在的。所以如果我们能将文件恢复到某一个版本,那么那个版本的文件就依然存在。
- 查看版本库信息
-
将版本库文件重置到某一个版本
-
这里的6520217就是版本Hash值,用于唯一确定版本库中此版本的标记,当然这是一个简短版,完整的比较长
-
如果不记得具体的版本值,版本值也可以使用HEAD值,比如最新的上一个版本:HEAD^,如果后退更多的版本,可以使用 HEAD~N
-
-
git reset --hard 6520217
Git分支
主干分支
默认情况下,Git软件就存在分支的概念,而且就是一个分支,称之为master分支,也称之为主干分支。
这就意味着,所有文件的版本管理操作都是在master这一个分支路线上进行完成的。
其他分支
就像之前说的,如果仅仅是一个分支,在某些情况并不能满足实际的需求,那么就需要创建多个不同的分支。
创建分支
-
git branch 分支名称
-
git branch user1
-
git branch user2
-
查看分支
- git branch -v
切换分支
我们将工作线路切换到user1
- git checkout 分支名称
- git checkout user1
此时我们添加新的文件user1.txt
然后提交到版本库
此时,查看分支信息,会发现user1分支的版本进度信息发生了改变
如果此时切换回到主干分支的话,那么b1.txt文件就不存在了,因为对应版本信息不一样
删除分支
如果觉得某一个分支建立的不太理想或已经没有必要在使用了,那么是可以将这个分支删除的。
- git branch -d 分支名称
- Git branch -d user2
Git合并
无论我们创建多少个分支,都是因为我们需要在不同的工作环境中进行工作,但是,最后都应该将所有的分支合在一起。形成一个整体。作为项目的最终结果。一般最后都是合并到我们的matser分支,也就是主分支
- git checkout 分支名
先清除主分支的内容
在user1分支添加user1.txt
在user2分支添加user2.txt
合并user1 user2分支内容到我们的主分支
Git冲突
在多分支并行处理时,每一个分支可能是基于不同版本的主干分支创建的。如果每隔分支都独立运行而不进行合并,就没有问题,但是如果在后续操作过程中进行合并的话,就有可能产生冲突。比如user1, user2的两个分支都是基于master分支创建出来的。B1分支如果和B2分支修改了同一份文件的话,那么在合并时,以哪一个文件为准呢,这就是所谓的冲突。
主分支添加test文件,内容为空
user1分支修改test文件
user2分支修改test文件
合并出现冲突
远程仓库拉取
通过HTTPS路径拉取
- git clone 对应url 进行仓库拉起到本地
通过SSH路径拉取
修改url为SSH的url
生成对应的SSH密钥
- 我们发现我们git push失败 ,因为缺少ssh公钥,所以连接失败
ssh-keygen -t rsa -C git@gitee.com:song-cheng-liu/gitee-test.git
来生成公钥- 一路回车 生成的密钥在我们的c/用户/用户名(你自己的)/.ssh/id_isa.pub
- 将我们的公钥复制到gitee对应的配置上