版本信息
时间 | 版本 | 描述 |
---|---|---|
2021-03 | 1.0 | git版本控制介绍 |
关于GIT
GIT是一个分布式版本控制系统;什么是“版本控制”?版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。
版本控制演变过程
本地版本控制
本地保存不同的版本,最流行的方式是RCS(一种用软件实现自动存储、检索、日志记录、识别、和合并修订的系统)
- 优点: 简单
- 缺点:出错率高
中心化版本控制
通过中央服务器,保存所有文件的修改版本,协同工作的用户通过客户端连接中央服务器,拉取最新的文件或者提交更新。代表系统有Subversion
- 优点:用户可以协同工作、管理员吧方便管理用户进度
- 缺点:中央服务器故障数据损坏恢复困难
分布式版本控制
客户端把代码仓库完整地镜像下来,包括完整的历史记录,操作完全本地。代表系统有git
- 优点:可以离线本地操作速度快,切换灵活;服务器故障可以通过任何一个本地镜像恢复数据包括提交记录;
- 缺点:工作目录只能是整个目录,不支持单个目录;权限控制一般通过文件读写权限实现;
git安装和配置
git安装
git配置
Git 自带一个 git config
的工具来帮助设置控制 Git 外观和行为的配置变量。
配置优先级:
项目内config(local) > 系统用户config(global) > git自带config(system)
通过命令git config --list --show-origin
可以查看配置及配置来源
常用配置命令如下,设置您的用户名和电子邮件地址,用于每次提交
git config --global user.name "张三"
git config --global user.email zs@abc.com
ssh公钥配置
cd ~/.ssh
# ssh-keygen -t rsa -C 'email@abc.com'
cat ~/.ssh/id_rsa.pub
# 添加公钥
git工作流程
本地开发的工作流程
基本概念
-
HEAD
HEAD
是当前分支引用的指针,它总是指向该分支上的最后一次提交。 这表示HEAD
将是下一次提交的父结点。 通常,可以把HEAD
看做你的上一次提交的快照。可以简单理解为: HEAD 指向分支(branch),分支指向提交 -
Index
Index(索引,或暂存区)是你预期的下一次提交
-
Workplace
工作目录
多人协作的工作流程
git传输协议
本地协议
本地协议(Local protocol) :远程版本库就是同一主机上的另一个目录
- 优点:基于文件系统的版本库的优点是简单,并且直接使用了现有的文件权限和网络访问权限。
- 缺点点:共享文件系统比较难配置,并且比起基本的网络连接访问,这不方便从多个位置访问
http协议
-
智能 HTTP 协议
智能 HTTP是运行在标准的 HTTP/S 端口上并且可以使用各种 HTTP 验证的协议
-
哑(Dumb) HTTP 协议
哑 HTTP 协议里 web 服务器仅把裸版本库当作普通文件来对待,提供文件服务
优点:1.支持账号密码授权 2.可用性高 3.传输速度快
缺点点:使用需授权的推送,管理凭证会比使用 SSH 密钥认证麻烦
ssh协议
ssh协议是一个验证授权的网络协议
- 优点:SSH 架设相对简单
- 缺点点:SSH 协议的缺点在于它不支持匿名访问 Git 仓库
git协议
git协议是包含在 Git 里的一个特殊的守护进程;它监听在一个特定的端口(9418),类似于 SSH 服务,但是访问无需任何授权
- 优点:网络传输快
- 缺点:缺乏授权机制
git内部原理
git 数据存储方式
Git实际上是一个键值对数据库(key-value data store)。 Git 存储内容的方式一个文件对应一条内容,存储一份数据,返回一个40位的 Hash 值作为键值。Hash 值的前两位作为目录,后38位为文件名。文件的内容就是 键值对 的 值 ,也就是 Git 存储的一系列数据。
git对象
git cat-file -t commitHash
查看文件对象类型
-
数据对象
数据对象来记录每一个文件的数据
-
树对象
Git 在每次提交时,会将暂存区的所有数据保存起来,产生一个 树对象 。树对象中的数据记录了在提交前,通过记录暂存区中每个文件的数据对象的 键 值,记录处于暂存区中的每个文件的状态。
-
提交对象
每次向 Git 仓库中提交文件时,Git 会生成一个提交对象,用以保存当前提交的信息,包括此次提交的父提交对象,作者的信息等
git命令
git help
基础命令
创建项目
-
git init
git init 初始化git仓库
-
git clone
git clone remoteUrl 克隆仓库
快照操作
-
git add
git add . 创建索引
-
git commit
git commit -a -m 'feat: message' 提交本地代码
-
git reset
-
reset后发生了什么?
- 移动 HEAD 指向的分支
- 使索引看起来像 HEAD
- 使工作目录看起来像索引
重置影响范围
-
“HEAD” 一列中的 “REF” 表示该命令移动了 HEAD 指向的分支引用,而 “HEAD” 则表示只移动了 HEAD 自身。 特别注意 WD Safe? 一列——如果它标记为 NO,那么运行该命令之前请考虑一下
- git revert
- git revert 和 git reset 的区别
- git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit
- git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入
日志
-
git log
git log 操作日志
-
git reflog
git reflog 全部操作日志
-
git diff
git diff
-
git status
git status 当前git状态查看
工具命令
贮藏
-
git stash
保存修改到本地,用于想要切换分支,但是还不想提交之前的改动
git stash list
git stash pop/apply
git stash branch branchName
git grep 搜索
分支管理命令
Git 的分支其实本质上仅仅是指向提交对象的可变指针
-
git branch
git branch -b branchName 从当前分支切换并创建新的分支
git branch -a 查看全部分支
-
git checkout
git checkout 切换分支
-
git fetch
git fetch 同步远程仓库信息到本地
-
git tag
git tag 标签列表
git tag tagName 打标签
-
git merge
git merge origin master 合并分支
-
git rebase
- git rebase origin master
-
git merge和 git rebase的区别
-
merge:自动创建一个新的commit
- 优点:记录了真实的commit情况,包括每个分支的详情
- 缺点:因为每次merge会自动产生一个merge commit,所以在使用一些git 的GUI tools,特别是commit比较频繁时,看到分支很杂乱
-
rebase: 会合并之前的commit历史
- 优点:得到更简洁的项目历史,去掉了merge commit
- 缺点:如果合并出现代码问题不容易定位,因为re-write了history
-
删除分支
-
git branch -d
git branch -d branchName 删除本地分支
git push origin -d branchName 删除远程分支
其他
-
git cherry-pick
将代码从一个分支转移到另一个分支(通常是部分变动)
git cherry-pick commitHash 合并某次提交
git cherry-pick branchName 合并分支的最新提交
git cherry-pick --coutinue 合并冲突后解决完成继续合并
git cherry-pick --abort 合并冲突还原
git常见场景
仓库迁移
问题描述:如何迁移代码到另一个仓库?
cd existing_repo
git remote rename origin old-origin
git remote add origin https://gitlab.com/dujf54732/test.git
git push -u origin --all
git push -u origin --tags
版本回退
问题描述:刚合并到master的代码发现有问题,需要将master 回滚到上一个版本,并且修复有问题代码后重新合并到master?
reset
git reset --hard commitHash # 重置到哪一个提交
git push origin -f branchName # 1有丢失代码风险 2如果又其他人协同开发,版本回退可能失败
# 其他人需要同步远程版本
git reset --hard origin/branchName
revert
# 回滚主分支代码
git checkout master
git checkout -b master-revert
git revert commitFrom^..commitEnd
git commit -a -m 'fix: revert to lastest'
git push origin master-revert
# 合并到master
# 修改版本分支缺陷
git checkout master
git fetch
git merge orgin/master
git checkout -b master-feature
# 挑选之前有效的代码
git cherry-pick commitHash1 commitHash1
# 修复缺陷
git commit -a -m 'fix: bugs'
git push origin master-feature
# 再次合并到master
git规范
分支规范
推荐合并到master的代码全部通过merge request,然后coding review后再合并到master,master禁止commit和push
提交规范
commit message格式
type: description
type常用类型
feat - 新功能 feature
fix - 修复 bug
docs - 文档注释
style - 代码格式(不影响代码运行的变动)
refactor - 重构、优化(既不增加新功能,也不是修复bug)
test - 增加测试
revert - 回退
build - 打包
description
对本次提交的描述,推荐以设置、修改、增加、删减、撤销开头。
feat: add XXXX
fix: 1. modify XXXX
2. modify XXXX