Git版本控制工具详解
(理解)认识版本控制和提供的功能
认识版本控制(版本控制)
- 什么是版本控制?
- 版本控制的英文是Version control
- 是维护工程蓝图的标准作法,能追踪工程蓝图从诞生一直到定案的过程
- 版本控制也是一种软件工程技巧,借此能在软件开发的过程中,确保由不同人所编辑的同一程序文件都得到同步
- 简单来说,版本控制在软件开发中,可以帮助程序员进行代码的追踪、维护、控制等等一系列的操作
版本控制的功能
- 对于我们日常开发,我们常常面临如下一些问题,通过版本控制可以很好的解决:
- 不同版本的存储管理:
- 一个项目会不断进行版本的迭代,来修复之前的一些问题、增加新的功能、需求,甚至包括项目的重构
- 如果我们通过手动来维护一系列的项目备份,简直是一场噩梦
- 重大版本的备份维护:
- 对于很多重大的版本,我们会进行备份管理
- 恢复之前的项目版本:
- 当我们开发过程中发生一些严重的问题时,想要恢复之前的操作或者回到之前某个版本
- 记录项目的点点滴滴:
- 如果我们每一个功能的修改、bug的修复、新的需求更改都需要记录下来,版本控制可以很好的解决
- 多人开发的代码合并:
- 项目中通常都是多人开发,将多人代码进行合并,并且在出现冲突时更好的进行处理
(了解)版本控制的历史和Git的诞生
版本控制的历史
- 版本控制的史前时代(没有版本控制):
- 人们通常通过文件备份的方式来进行管理,再通过diff命令来对比两个文件的差异
- CVS(Concurrent Versions System)
- 第一个被大规模使用的版本控制工具,诞生于1985年
- 由荷兰阿姆斯特丹VU大学的Dick Grune教授实现的,也算是SVN的前身(SVN的出现就是为了取代CVS的)
- SVN(Subversion)
- 因其命令行工具名为svn因此通常被简称为SVN
- SVN由CollabNet公司于2000年资助并发起开发,目的是取代CVS,对CVS进行了很多的优化
- SVN和CVS一样,也属于集中式版本控制工具
- SVN在早期公司开发中使用率非常高,但是目前已经被Git取代
- Git(Linus的作品)
- 早期的时候,Linux社区使用的是BitKeeper来进行版本控制
- 但是因为一些原因,BitKeeper想要收回对Linux社区的免费授权
- 于是Linus用了大概一周的时间,开发了Git用来取代BitKeeper
- Linus完成了Git的核心设计,在之后Linus功成身退,将Git交由另外一个Git的主要贡献者Junio C Hamano来维护
集中式版本控制
- CVS和SVN都是是属于集中式版本控制系统(Centralized Version Control Systems,简称 CVCS)
- 它们的主要特点是单一的集中管理的服务器,保存所有文件的修订版本
- 协同开发人员通过客户端连接到这台服务器,取出最新的文件或者提交更新
- 这种做法带来了许多好处,特别是相较于老式的本地管理来说,每个人都可以在一定程度上看到项目中的其他人正在做些什么
- 但是集中式版本控制也有一个核心的问题:中央服务器不能出现故障:
- 如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作
- 如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据
(理解)集中式和分布式版本控制的区别
分布式版本控制
- Git是属于分布式版本控制系统(Distributed Version Control System,简称 DVCS)
- 客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录
- 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复
- 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份
- 目前在公司开发中我们都是使用Git来管理项目的
(掌握)Git的安装和安装内容的说明
Git的安装
- 电脑上要想使用Git,我们需要先对Git进行安装:
- Git的官网:https://git-scm.com/downloads
- 根据自己的操作系统下载Git即可;
- 在window操作系统按照默认配置全局安装即可
Bash – CMD – GUI 区别
- Bash,Unix shell 的一种,Linux 与 Mac OS X 都将它作为默认 shell
- Git Bash 就是一个 shell,是 Windows 下的命令行工具,可以执行 Linux 命令
- Git Bash 是基于 CMD 的,在 CMD 的基础上增添一些新的命令与功能
- 所以建议在使用的时候,用 Bash 更加方便
- Git CMD
- 命令行提示符(CMD)是 Windows 操作系统上的命令行解释程序
- 当你在 Windows 上安装 git 并且习惯使用命令行时,可以使用 cmd 来运行 git 命令
- Git GUI
- 基本上针对那些不喜欢黑屏(即命令行)编码的人
- 它提供了一个图形用户界面来运行 git 命令
Git的配置分类
- 既然已经在系统上安装了 Git,你会需要做几件事来定制你的 Git 环境:
- 每台计算机上只需要配置一次,程序升级时会保留配置信息
- 你可以在任何时候再次通过运行命令来修改它们
- Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量:
- /etc/gitconfig 文件:包含系统上每一个用户及他们仓库的通用配置
如果在执行 git config 时带上 --system 选项,那么它就会读写该文件中的配置变量
由于它是系统配置文件,因此你需要管理员或超级用户权限来修改它。(开发中通常不修改) - ~/.gitconfig 或 C/用户/XiaoYu/.gitconfig 文件:只针对当前用户
你可以传递 --global 选项让 Git 读写此文件,这会对你系统上 所有 的仓库生效 - 当前使用仓库的 Git 目录中的 config 文件(即 .git/config):针对该仓库
你可以传递 --local 选项让 Git 强制读写此文件,虽然默认情况下用的就是它
(掌握)Git操作-Git初始化和clone远程仓库
Git的配置选项
- 安装Git后,要做的第一件事就是设置你的用户名和邮件地址
- 这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改
- 如果使用了 --global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息
git config --global user.name "XiaoYu" git user.emial "你的邮箱"
- 检测当前的配置信息:git config --list
Git的别名(alias)
- Git 并不会在你输入部分命令时自动推断出你想要的命令:
- 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名
//举例: //它用于为 Git 设置一个全局别名(alias)来简化 checkout 命令的使用。具体来说,它会将 co 作为 checkout 命令的别名,这样你可以在命令行中使用 git co 代替 git checkout,从而更加快速和方便地切换 Git 分支 git config --global alias.co checkout //使用这个命令的时候需要保证已经安装了 Git,并且在命令行中执行该命令。--global 标志表示该别名将被设置为全局别名,即在电脑的任何 Git 仓库中都可以使用 git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status
获取Git仓库 – git init/git clone
- 我们需要一个Git来管理源代码,那么我们本地也需要有一个Git仓库。
- 通常有两种获取 Git 项目仓库的方式:
- 方式一:初始化一个Git仓库,并且可以将当前项目的文件都添加到Git仓库中(目前很多的脚手架在创建项目时都会默认创建一个Git仓库)
- 方式二:从其它服务器 克隆(clone) 一个已存在的 Git 仓库(第一天到公司通常我们需要做这个操作)
- 方式一:初始化Git仓库
- 该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的核心
- 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪
git init//初始化仓库 Initialized empty Git repository in "地址"//git初始化好仓库返回提示 git add "文件"//这是将文件加入仓库最单纯的方式 git add .//你也可以这么做,相当于将所有文件都加进去,省得一个个加很麻烦 git log//查看我们提交了什么 e(exit)//使用git log查看完需要使用q才能退出查看效果
- 方式二:从Git远程仓库
//克隆下来别人在GitHub的仓库 git clone https://github.com/2002XiaoYu/Latest-front-end-Notes.git
(掌握)Git操作-文件状态的划分
文件的状态划分
- 现在我们的电脑上已经有一个Git仓库:
- 在实际开发中,你需要将某些文件交由这个Git仓库来管理
- 并且我们之后会修改文件的内容,当达成某一个目标时,想要记录下来这次操作,就会将它提交到仓库中
- 那么我们需要对文件来划分不同的状态,以确定这个文件是否已经归于Git仓库的管理:
- 未跟踪:默认情况下,Git仓库下的文件也没有添加到Git仓库管理中,我们需要通过add命令来操作
- 已跟踪:添加到Git仓库管理的文件处于已跟踪状态,Git可以对其进行各种跟踪管理
- 已跟踪的文件又可以进行细分状态划分:
- staged(暂缓):暂缓区中的文件状态,你
git log
是看不到的,但是他已经放到索引区里面了,只是没有跟commit对象联系起来(意思就是你还没跟任何的一次提交联系在一起) - Unmodified:commit命令,可以将staged中文件提交到Git仓库
- Modified:修改了某个文件后,会处于Modified状态(就是处于已经修改的状态,但是还没丢到暂缓区去),我们可以使用
git commit -m "添加某个文件和修改某个文件"
将这次修改也提交到暂缓区。等一大波操作结束可以将其重新放到git仓库
- 在工作时,你可以选择性地将这些修改过的文件放入暂存区
- 然后提交所有已暂存的修改,如此反复。但是不管你是新增的文件还是修改的文件(包括已经在git仓库但进行的修改)都得先经过暂缓区
Git操作流程图
Alice's Loacal Repo |
对应本地仓库 |
Remote Repo |
远程仓库 |
Bob's Local Repo |
本地仓库 |
Working Directory |
工作区 |
Index |
对应着索引区,也就是staged |
.git Directory |
git仓库(目录) |
git add. git commit -m "" //命令合二为一 git commit -a -m "aaaa"//直接将工作区的内容提交到仓库(本地的,也交暂存区) //-a 标志告诉 Git 自动将所有已修改和已删除的文件添加到暂存区中,这样你就不必使用 git add 命令显式地将更改添加到暂存区了。 //-m "aaaa" 标志用于指定本次提交的提交信息。 "aaaa" 是提交信息的内容,它应该简洁地描述了这个提交所做的更改
(掌握)Git操作-add-commit-status
检测文件的状态 - git status
- 我们在有Git仓库的目录下新建一个文件,查看文件的状态:
git status//查看状态命令(完整状态)
- Untracked files:未跟踪的文件
- 未跟踪的文件意味着 Git 在之前的提交中没有这些文件
- Git 不会自动将之纳入跟踪范围,除非你明明白白地告诉它“我需要跟踪该文件”
- 我们也可以查看更加简洁的状态信息:
//都是用来查看 Git 仓库当前状态的命令。它们的作用是一样的,都会以缩略的形式输出 Git 仓库中尚未提交的更改的概要信息。命令的输出是一样的,只是两者的命令参数略有不同。-s 是 --short 的简写形式 git status -s git status --short //两个字符的状态标识符,表示文件的状态。例如,M 表示文件已经修改,A 表示文件已经添加到暂存区,?? 表示文件未被跟踪等等。 //空格字符。 //文件名或路径。 //输出的状态标识符和文件名之间用空格分隔,每个文件占据一行。
M index.html//index.html 文件已经被修改但未添加到暂存区 A images/logo.png//images/logo.png 文件已经添加到暂存区 ?? README.md//README.md 文件是一个未被跟踪的新文件 //左栏指明了暂存区的状态,右栏指明了工作区的状态
文件添加到暂存区 – git add
- 跟踪新文件命令:
使用命令 git add 开始跟踪一个文件
git add aaa.js
- 跟踪修改的文件命令:
- 如果我们已经跟踪了某一个文件,这个时候修改了文件也需要重新添加到暂存区中
跟踪文件:
修改了文件(需要先经过暂存区):
- 通过git add . 将所有的文件添加到暂存区中:
(掌握)Git操作-Git忽略文件的配置方式
git忽略文件
- 一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表
- 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等
- 我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式(
ignore
的英文意思为忽略
) - 不想要git跟踪这些文件,就可以将这个文件的名字写进
.gitignore
里面,例如不想要他跟着xiaoyu.js文件,就直接写上xiaoyu.js然后独占一行就行了
- 在实际开发中,这个文件通常不需要手动创建,在必须的时候添加自己的忽略内容即可
- 比如下面是创建的Vue项目自动创建的忽略文件:
- 包括一些不需要提交的文件、文件夹
- 包括本地环境变量文件
- 包括一些日志文件
- 包括一些编辑器自动生成的文件
.DS_Store |
Mac电脑会自动生成的文件 |
node_modules |
包管理器,这个也不需要,我们只需要对应版本的package.json和lock.json文件就行了 |
/dist |
打包后的文件直接部署了,不需要放仓库里(况且压缩过了也很难看懂改了啥) |
**.env,local和.evc..local |
本地文件,后面会写这些的作用 |
Log files底下的那些.log* |
这些都是日志文件(工具生成的,用来记录一些bug之类的) |
Editor directories and files |
编辑器自动生成的文件 |
Github提供的各个语言中需要忽略的文件项目(基本上不需要额外配置,脚手架也会默认配置):
(掌握)Git操作-Git校验和-日志和版本回退
文件更新提交 – git commit
- 现在的暂存区已经准备就绪,可以提交了
- 每次准备提交前,先用 git status 看下,你所需要的文件是不是都已暂存起来了
- 再运行提交命令 git commit
- 可以在 commit 命令后添加 -m 选项,将提交信息与命令放在同一行
git commit -m "提交信息"//刚刚有讲到
- 如果我们修改文件的add操作,加上commit的操作有点繁琐,那么可以将两个命令结合来使用:
git commit -a -m "修改了bbb文件"
Git的校验和
- Git 中所有的数据在存储前都计算校验和,然后以 校验和 来引用
- Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)
- 这是一个由 40 个十六进制字符(0-9 和 a-f)组成的字符串,基于 Git 中文件的内容或目录结构计算出来
A B C分别是3次提交,我们每一次提交都是一次快照,我们可以通过校验和找到tree,在通过tree找到所有的文件,所谓的版本回退一样是找以前的校验和,然后找到对应的索引tree,在通过tree找到对应的文件,然后再将这些文件恢复到我们目前提交的状态
查看提交的历史 – git log
- 在提交了若干更新,又或者克隆了某个项目之后,有时候我们想要查看一下所有的历史提交记录
- 这个时候我们可以使用git log命令:
- 不传入任何参数的默认情况下,git log 会按时间先后顺序列出所有的提交,最近的更新排在最上面
- 这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明
git log//提交过多可以按空格继续往下看内容
git log --pretty=oneline --graph(图结构)//显示 Git 仓库的提交历史,它会将提交历史以 ASCII 码图的形式展示出来 //显示提交历史:该命令会显示 Git 仓库的提交历史,包括每次提交的 SHA-1 校验和、提交信息和提交日期等信息。 //显示分支结构:--graph 选项会在 ASCII 码图中显示分支结构,使得更容易看出不同分支之间的关系和合并情况。 //美化输出格式:--pretty=oneline 选项会将每个提交压缩成一行,使得输出更加紧凑和易于阅读。 //可以更清晰地了解 Git 仓库的提交历史,从而更好地管理代码版本,特别是在多人协作的项目中
上面的图是一开始所处的状态(不加--graph),你会发现下面的图左边还有图形化的分支,这是加上--graph 选项的显示方式,用*
做出了区分
git log --pretty=oneline//不加graph,输出前面没有*
版本回退 – git reset
- 如果想要进行版本回退,我们需要先知道目前处于哪一个版本:Git通过HEAD指针记录当前版本
- HEAD 是当前分支引用的指针,它总是指向该分支上的最后一次提交
- 理解 HEAD 的最简方式,就是将它看做 该分支上的最后一次提交 的快照
- reset = 重置
- 我们可以通过HEAD来改变Git目前的版本指向:
- 上一个版本就是HEAD,上上一个版本就是HEAD^
- 如果是上1000个版本,我们可以使用HEAD~1000
- 我们可以可以指定某一个commit id
git reset --hard HEAD^ //这个命令会将当前分支的 HEAD 指针重置到上一次提交(也就是父提交),并将工作区和暂存区的内容也回退到上一次提交时的状态。这相当于撤销了最近一次的提交,并把代码回滚到了上一次提交的状态 git reset --hard HEAD~1000 //这个命令会将当前分支的 HEAD 指针重置到前1000次提交的位置,并将工作区和暂存区的内容也回退到该提交时的状态。这相当于回滚到前1000次提交的状态,慎用 git reset --hard 2d44982 //这个命令会将当前分支的 HEAD 指针重置到指定的提交 2d44982,并将工作区和暂存区的内容也回退到该提交时的状态。这相当于回滚到指定提交的状态 //git reset --hard 命令是一种危险的操作,因为它会删除当前分支指向的提交之后的所有提交,如果你不小心操作可能会丢失你的代码修改。所以在使用这个命令时,要非常小心并且确保备份了重要的代码修改
移动HEAD就进行切换版本
git reflog//记录下来我们每一次的操作
Git版本控制工具详解(二)https://developer.aliyun.com/article/1470456