git 总结
一、版本控制
1.1 定义
- 维护工程蓝图的标准作法,能追踪工程蓝图从诞生一直到定案的过程
- 是一种软件工程技巧,确保由不同人所编辑的同一程序文件都得到同步
- 作用:在软件开发中,可以帮助程序员进行代码的追踪、维护、控制等等一系列的操作
1.2 版本控制的功能
- 不同版本的存储管理:一个项目会不断进行版本的迭代,来修复之前的一些问题、增加新的功能、需求设置包括项目的重构
- 重大版本的备份维护
- 恢复之前的项目版本
- 记录项目的点点滴滴
- 多人开发的代码合并
1.3 版本控制的历史
- 没有版本控制:diff 命令
- CVS:第一个大规模使用的版本控制工具
- SVN
- Git(Linus作品)
1.4 分类
- 集中式版本控制(简称 CVCS) 比如 CVS 和 SVN
- 主要特点是单一的集中管理的服务器,保存所有文件的修订版本
- 本地没有保存记录,只有中央服务器才有协同开发人员通过客户端连接到这台服务器,取出最新的文件或者提交更新
- 集中式版本控制有一个核心的问题:中央服务器不能出现故障
- 每个人都可以一定程度上看到项目中的其他人正在做什么
- 分布式版本控制 (简称 DVCS) 比如 git
- 客户端把代码仓库完整地镜像下来,包括完整的历史记录
- 任何移一处协同工作的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复
- 每一次克隆,都是一次对代码仓库的完整备份
- 小结
- 集中式版本控制是将整个仓库放服务器
- 分布式版本控制是每台电脑都有对应的仓库,可以在本地提交,然后把本地仓库同步到服务器的仓库里
二、Git
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
2.1 安装过程
- 官网:Git
- 安装之后会有以下三个工具
Git bash
git cmd
git gui
- 本质上都是执行命令
2.2 Git的配置分类
- 定制Git 环境
- 每台计算机上只需要配置一次,程序升级时会保留配置信息
- 可以在任何时候再次通过运行命令来修改它们
2.3 Git的配置选项
- 安装之后,要做的第一件事情就是设置用户名和邮箱地址
$ git config --global user.name "youlishu"
$ git config --global user.email "xxxxxxxxxxxxxxxxxxxxxxxx"
- 检测当前的配置信息:
git config --list
q
:退出- 修改:直接重新设置进行覆盖
三、Git操作
3.1 获取Git仓库
-
配置 VSCode 为 git bash
-
项目的两种情况
- 新项目:进入到文件夹(对哪个文件进行管理)
-
初始化一个git仓库:
git init
-
将当前目录的所有东西加入到git暂缓区:
git add .
-
将所有文件提交到本地仓库里面:
git commit -m "初始化项目"
-
查看提交的信息:
git log
-
- 已经有远程仓库:将远程仓库的代码拿下来,在本地仓库里面开发,开发完之后将代码提交到远程仓库
git clone 地址
- 文件名可修改
- 新项目:进入到文件夹(对哪个文件进行管理)
3.2 文件的状态划分
在实际开发中,需要将某些文件交由这个Git仓库来管理。
并且我们之后会修改文件的内容,当达成某一个目标时,想要记录下来这次操作,就会将它提交到仓库中。
需要对文件来划分不同的状态,以确定这个文件是否已经归于Git仓库的管理。
对文件状态进行划分:
Untracked
未跟踪的文件- 没有通过 git 追踪的文件
- 使用
git add 文件名
使得该文件被追踪
tracked
:已跟踪的文件staged
:暂存区(索引区)中的文件状态,已经在跟踪了- git log 是查看不到的
- 已经提交到 git 本地缓存中的文件
- 提交缓存之前需要将文件添加到暂存区(索引区) git add .
- 之后进行
git commit -m "提交信息"
将文件提交到缓存(本地仓库)中 - 简写
git commit -a -m ""
- 取消暂存状态:
git rm --cached 文件名
unmodified
commit
命令,可以将staged
中文件提交到 Git 仓库- 已被git记录,但是还没有被修改(比如 新创建的文件 )
modified
:修改了某个文件后,会处于 Modified 状态,暂时没有进行缓存,需要重新 commit
3.3 检测文件的状态
-
git status
-
添加到暂缓区:
git add js/nba.js
-
提交:
git commit -m "修改了nba文件"
-
查看更加简洁的信息
git status -s
git status --short
3.4 文件添加到暂存区
- 使用 git add 开始跟踪一个文件
- 跟踪新文件命令:
git add aaa.js
- 将所有的文件添加到暂存区:
git add .
3.5 文件更新提交
git status
看所需要文件是否暂存起来了- 将暂存区的改动提交到本地git仓库(一般是具有某个特定意义的工作作为一个版本,可以是多个文件的变化)
git commit -m "提交信息"
- 结合使用:git commit -a -m “修改了bbb文件”
- 查看本地仓库存储的文件:
git ls-files
- 从本地仓库回退到暂存区:
git reset --soft <commit id>
- 修复提交(替换上一次提交),不增加一个新的提交版本的情况下将新修改的代码追加到前一次的提交中:
git commit --amend -m ""
3.6 查看提交的历史
git log
- 可看到 commit id
- 多个分支的时候:
git log --pretty=oneline --graph
- 显示一行:
git log --pretty=oneline
space
查看下一条- 查看所有的历史提交,记录了详细的各种操作:git reflog
3.7 版本回退
- git 通过 Head 指针记录当前版本
- head:该分支上的最后一次提交的快照
- 移动 head
- 回退上个版本:
git reset --hard HEAD^
- 回退上上个版本:
git reset --hard HEAD^^
- 回退到第1000个版本:
git reset --hard~1000
git reset --hard [commit id]
后面的commit id
通过git reflog
命令查看commit id
:校验和,可选择前面七/八位
- 回退上个版本:
3.8 Git标签
- 作用:打上标签,表示它的重要性
- 创建标签:
- 轻量标签:
git tab v1.0
- 附注标签:
git tag -a v1.2.0 -m "附注标签"
- 轻量标签:
- 推送标签到远程服务器上:
git push origin --tags
git push origin v1.0
- 删除本地tag:git tag -d v1.0.0
- 删除远程服务器中tag:
git push origin -d v1.0.0
- 查看标签所指的版本:git checkout v1.0.0,通常我们在检出 tag 的时候还会创建一个对应的分支
四、远程仓库
3.1 概念
- 远程服务器通常是搭建在某一个服务器上的
- 需要在Git服务器上搭建一个远程仓库
- 第三方服务器
- GitHub
- Gitee
- Gitlab
- 在自己服务器(云服务器)安装 gitlab 软件使用 Gitlab
- 一台 git 服务器可以创建很多个远程仓库
- git 服务器跑在云服务器里面
- 第三方服务器
3.2 远程仓库的验证
- 远程仓库
- GitHub
- Gitee
- 自己搭建
- git clone 地址
- https
- ssh
- 手段
- 基于http的凭证存储:控制面板中window凭证
- 基于ssh的密钥
3.3 远程仓库的验证
- 凭证
- 无状态:不会记录原来已经访问过了,每一个连接都需要用户名和密码
- git提供了 凭证系统 来处理
- SSH密钥
- 以非对称加密实现身份验证
- 人工生成一对公钥和私钥,通过生成的密钥进行认证,这样就可以在不输入密码的情况下登录
- 公钥需要放在待访问的电脑之中,而对应的私钥需要由用户自行保管电脑上命令行输入一串命令:
- 会生成公钥和私钥
# 选择以下其中一种
ssh-keygen -t ed25519 -C "your email"
ssh-keygen -t rsa -b 2048 -C "your email"
- 公钥 放在服务器
- 远程服务器对其私钥进行配
- 在c盘的用户的
.ssh
中可以找到
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJnhey0vDCpD4FS+Flv530fNTu09YYSHGeb s22222a@111.com
3.4 管理远程仓库
- 查看远程仓库
git remote
- 得到详细信息:git remote -v
- 让本地仓库和远程仓库建立连接,一个本地仓库可以和多个远程仓库建立连接(直接clone就不需要)
git remote add origin(名字) 远程仓库地址
- 拉取失败时(不知道本地master分支和远程仓库哪一个分支建立联系) 输入以下代码
- git pull origin master --allow-unrelated-historied
- 指定哪一个远程仓库分支
- push之前需要把服务器的东西拿下来:
git pull
- pull本质:
fetch+merge
- pull本质:
- git push:将本地代码push到远程仓库里面
- 给本地仓库设置上游(跟踪)分支,之后提交代码就不需要指定分支:git branch --set-upstream-to=origin/master
3.5 远程仓库的交互
-
git clone 地址
-
git push
:将本地仓库的代码推送到远程仓库中- 默认是将当前分支
push
到 origin远程仓库 :git push origin master
- 默认是将当前分支
-
git fetch
从远程仓库中获取代码- 默认是从
origin远程仓库
中获取代码:git fetch origin master
- 默认是从
-
git merge
:通过merge
来合并当前的代码git merge origin/master
-
git pull:从远程仓库中
pull
代码- ===
git fetch + git merge(rebase)
- ===
3.6 总结
- 有项目
- git clone xxxxxxxxxxxxxx
- 进行开发
- git add .
- git commit -m “提交”
- git pull(git fetch/ git merge)
- git push
- 新项目方式一
- 创建远程仓库
- git clone xxxxxxx
- …同上
- 新项目方式二
- 创建本地仓库搭建本地项目
- git init
- git add .
- git commit -m “”
git remote add origin xxxxx
git pull origin master --allow-unrelated-histories
- git branch --set-upstream-to= origin/master master
- git fetch
- git merge --allow-unrelated-histories
- git push
- 推送分支并且设置为远程分支:
git push --set-upstream origin master
- 创建本地仓库搭建本地项目
3.7 Git提交对象
git add .
提交后编译成二进制文件git cat-file -t f178
查看是什么文件git cat-file -p f178
查看文件内容
3.8 Git master分支
- git的分支,本质上仅仅是指向提交对象的可变指针
- 每次提交都会有一个
commit
对象,通过parent
属性连接在一起 commit
对象形成的工作流是在整个分支里面完成的,这个分支是默认情况下git帮我们创建的分支master
master分支
每次提交时自动移动
3.9 Git创建分支
本质
- 只是创建了一个可以移动的新的指针
- 创建 testing 分支:
git branch testing
- 切换对应的分支:
git checkout testing
- 通过一个名为 HEAD 的特殊指针知道在哪一个分支
- 不同分支看到的代码不同
- 创建分支并且切换分支:
git checkout -b dev
- 查看所有的分支:
git branch
为什么要使用分支?
前边的版本出现了bug,而又在开发新的功能,需要以下步骤
- 回退到出现bug的版本:
git checkout v1.0.1
- 创建新的分支进行代码修复:
git checkout -b hotfix
- 修复完所有的bug,打上tag:
git tag v1.0.2
- 切回到master分支:
git checkout master
- 修复好的分支和master进行合并:
git merge hotfix
- 代码出现冲突(一般不会发生):上面部分是当前代码,下面部分是修复的代码,两者修改的是同一个文件
- 手动删除
- 编辑器中接收当前的改变|接收合并进来的代码 | 保留两者代码 | 比较
- 代码出现冲突(一般不会发生):上面部分是当前代码,下面部分是修复的代码,两者修改的是同一个文件
- 合并后的分支有两个父节点
3.10 查看和删除分支
- 查看当前所有的分支:git branch
- 同时查看最后一次提交:git branch -v
- 查看所有合并到当前分支的分支:git branch --merged
- 查看所有没有合并到当前分支的分支:git branch --no-merged
- 移除分支(指针),提交历史不会移除:git branch -d hotfix
- 强制删除某一个分支:git branch -D hotfix
3.11 git的工作流
Git上分支的使用的便捷性,产生了很多Git的工作流:在整个项目开发周期的不同阶段,可以同时拥有多个开放的分支,定期地把某些主题分支合并入其他分支中。
-
不仅仅是产生bug才创建分支
-
大多数是存在很多分支
- master 作为主分支
- develop作为开发分支,并且有稳定版本时,合并到 master 分支中
- topic 作为某一个主题或者功能或者特性的分支进行开发,开发完成之后合并到develop之中
gitGraph
commit
branch develop
commit
commit
commit
commit
branch topic
commit
commit
checkout main
commit
commit
(mermaid 语法显示不出来…)
开发的东西在develop分支,每天提交十多次,在develop中开发形成了一个比较稳定的版本回到master分支进行合并,master中只保留那些重要的版本,可以打上tag,topic是产品突发奇想,可能实现不了,实现了,两次合并🙃
3.12 比较常见的git flow
- release分支:准备发布的版本,创建新的分支让测试进行测试,发现 bug 再次创建分支修复,之后合并到 dev 和 master
3.13 分支
- 查看分支:
git branch
- 创建分支:
git branch 分支名称
- 切换分支:
git checkout 分支名称
- 创建并切换:
git checkout -b 分支名称
- 分支合并:
# B合并到A,需要切换到A分支
git merge 被合并分支
# 查看已经合并的分支
git branch --merged
# 查看未合并的分支
git branch --no-merged
- 删除分支
# 如果分支为未合并状态,则不允许删除
git branch -d 分支名称
# 强制删除
git branch -D 分支名称
五、Git的远程分支
5.1 介绍
- 远程分支也是一种分支结构
- 添加远程仓库步骤
-
git remote add origin xxxxx(到下方a)
-
git fetch origin main
:在本地中拿到 origin/main 分支- 远程仓库名字可能为 master
-
git branch --set-upstream-to=origin/main main
:给当前分支设置上游分支,master开始跟踪它 -
git merge
:默认合并上游分支,但是要有共同祖先,改成:git merge --allow-unrelated histories
-
git config push.default upstream
:用上游分支 -
git push
-
- 本地分支 master,远程分支 main
git checkout --track origin/main
:准备跟踪远程分支,就有main分支了- 可以删除master分支:
git branch -d master
- git pull
- 当在本地branch dev分支进行开发,推送到远程时,本质操作为:
git push origin dev:dev
- 远程也需要
dev
分支 - 直接推送到远程dev:git push origin dev
- 方便后续提交可设置dev的上游分支:
git branch --set-upstream-to=origin/dev
- 远程也需要
- 本地和远程分支名字最好一致
5.2 远程分支的管理
git push origin develop
:直接将本地分支推到远程git branch --set-upstream-to = origin/develop
:创建上游分支- 角色
- 作为组员
- git clone xxxxx:默认克隆下来的是main分支
- 进入终端
- 切换到develop分支:
git checkout --track origin/develop
(简写:git checkout develop)- 检查远程仓库是否有这个分支
- 在本地创建develop分支
- 让本地develop分支跟踪远程分支
- 切换到develop分支
- 作为组员
- 删除远程分支:git push origin --delete feature
- 删除本地分支:
git branch -d feature
5.3 Git的rebase用法
-
改变当前分支
base
-
变成线性结构,通过
git log--pretty=online
查看为线性结构 -
git checkout feature
-
git rebase master
- 原来的base是bbb
- 重新rebase让其指向master所指向的提交
-
git checkout master
:切换到master分支 -
git merge feature:master会往后面移动
-
整个历史记录变得非常整洁
5.4 rebase的原理
- 找到两个分支最近的祖先,对比当前的祖先历次的提交已到
master
后面 - 切换到
feature
分支:git rebase master
- 切换到
master
分支进行merge
5.5 rebase和merge的选择
rebase
:简化历史记录merge
:记录所有的历史merge
:将两者合并成一个新的提交对象- 提交历史变成非线性结构
- rebase master非常危险,尽量不要改变主流程,会造成大量的提交历史在 main 分支中不同
六、额外补充
6.1 git忽略文件
- 不希望git跟踪和管理
- 配置
.gitignore
文件 - 通常是自动生成的文件:日志文件、编译过程中创建的临时文件
6.2 开源项目许可证说明
6.3 git的校验和
- Git中所有的数据在存储前都计算校验和
- 使用校验和和引用
七、Git中常见的命令总结
- 基础的命令:
git clone xxxxxxxx
git add .
git commit -m "xxxx"
git pull ->(git fetch + git merge)
git push
- 进阶的命令:
- main
- develop
- feature
git checkout develop
# 1.检查服务器是否有origin/develop这个分支
# 2.创建一个本地的develop分支
# 3.让本地的develop分支自动跟踪origin/develop
# 4.切换到develop分支
git add .
git commit -m ""
git pull
git push
- 高级的命令:
git tag
git checkout -b develop
git push origin develop
git merge develop
git rebase
八、提交规范
- feat: 新增功能或特性
- fix: 修复 bug
- docs: 只涉及文档的更改
- style: 代码格式化的更改,不影响代码多级
- refactor: 代码格式化的更改,不包括 bug 修复、新增功能或文档编辑
- perf: 提高性能的代码更改
- chore: 构建过程或辅助工具的更改
九、工作日常
9.1 增删改查
- 增:
- git add .
- git commit -m “chore: 哈哈哈”
- 删:
- git reset 文件名
- 改:
- git commit --amend -m “fix: 修改提交记录”
9.2 合并分支六部曲
- git checkout test
- git pull
- git merge dev-name(别在自己的分支上瞎合并,会变得不干净呜呜呜)
- 跑项目看是否一切正常
- git push origin test
- git checkout dev-name(血泪教训一定要切换回来,不然下一次直接推送上去惹!)