Git
0x01 概述
- Git 是一个免费、开源的分布式版本控制系统,其使用一个叫做仓库的数据库来记录文件的变化
- 仓库中每个文件都有一个完整的版本历史记录
- 版本控制系统 Version Control System
- 集中式,如 SVN、CVS 等
- 所有文件都集中保存在中央服务器上,每个用户仅保存一份副本
- 当需要修改时,需要从中央服务器上下载最新版本,修改后传回
- 优点:管理简单
- 缺点:当中央服务器出现单点故障问题时,用户 就会无法工作
- 分布式,如 Git、Mercurial 等
- 每个人电脑上都有一个完整的版本库,当需要将修改内容分享给其他人时,只需要将仓库互相同步一下即可
- 集中式,如 SVN、CVS 等
- Git 特点
- 免费开源
- 速度快
- 功能强大
- 支持离线工作
- 强大的分支管理
0x02 安装与配置
- 安装操作系统在官网下载相应版本
- 使用方式
- CLI
- GUI
- 官网下载 GUI 工具
- IDE 插件/扩展
- 使用命令
git config
配置 Git- 配置用户名:
git config --global user.name "user name"
配置邮箱:git config --global user.email 123@123.com
保存用户名和密码:git config --global credential.helper store
查看 Git 配置信息:git config --global --list
--global
:全局配置,对所有仓库生效--system
:系统配置,对所有用户生效- 省略:本地配置,仅对本地仓库有效
- 配置用户名:
0x03 新建仓库
(1)仓库概述
- 仓库(Repository,简称 Repo)又称版本库
- 仓库可以理解成目录,目录中所有文件都可以被 Git 管理起来
- Git 可以跟踪每一次增删改操作,从而可以回滚到历史版本
(2)创建仓库
- 使用命令
git init
直接在本地创建一个仓库- 在空目录 git-test 中创建仓库:
git init
- 在非空目录中创建 git-temp 仓库:
git init git-temp
- 在空目录 git-test 中创建仓库:
- 使用命令
git clone
从远程服务器克隆一个已经存在的仓库- 克隆远程服务器中某个仓库:
git clone https://github.com/name/xxx.git
- 克隆远程服务器中某个仓库:
0x04 工作区域和文件状态
(1)工作区域
- 工作区 Working Directory
- 资源管理器中可以看到的文件夹
.git
所在目录- 使用命令
git add
将新内容提交到暂存区
- 暂存区 Staging Area/ 索引 Index
- 一种临时存储区域,用于保存即将提交到 Git 仓库的修改内容
.git/index
- 使用命令
gitcommit
将新内容提交到本地仓库
- 本地仓库 Local Repository
- 包含完整的项目历史和元数据,是 Git 存储代码和版本信息的主要位置
.git/objects
(2)文件状态
- 未跟踪 Untrack
- 已创建但未被 Git 管理的文件
- 未修改 Unmodified
- 未跟踪文件中被 Git 管理后未修改过的文件
- 已修改 Modified
- 未修改文件中被修改过的文件
- 已暂存 Staged
- 修改过的文件并暂存的文件
graph LR
A(未跟踪)--git add-->B(未修改)
B--修改文件-->C(已修改)
C--git add-->D(已暂存)
A--git add-->D
B--git rm-->A
D--git commit-->B
D--git reset-->C
C--git checkout-->B
0x05 添加和提交文件
- 使用命令
git init
创建仓库 - 使用命令
git status
查看仓库的状态 - 使用命令
git add
添加到暂存区- 将文件 file.txt 添加到暂存区:
git add file.txt
- 将所有 txt 文件添加到暂存区:
git add *.txt
- 将所有文件添加到暂存区:
git add .
- 将文件 file.txt 添加到暂存区:
- 使用命令
git commit
提交- 将暂存区文件提交到仓库中:
git commit -m "message"
-m
参数用于指定提交的说明信息
- 仅提交处于暂存区的文件
- 将暂存区文件提交到仓库中:
- 使用命令
git log
查看提交记录- 查看简洁的提交记录:
git log --oneline
- 查看简洁的提交记录:
0x06 回退版本
- 使用命令
git reset
回退版本,可以退回到之前某一指定的提交状态
git reset --soft
:回退到某一版本并保留工作区和暂存区的所有修改内容git reset --hard
:回退到某一版本并舍弃工作区和暂存区的所有修改内容git reset --mixed
:默认参数,回退到某一版本并只保留工作区的所有修改内容
0x07 查看差异
- 使用命令
git diff
可以查看文件在工作区、暂存区、版本库之间的差异;也可以查看两个指定版本或两个分支之间的差异 - 当不添加其他参数时,默认比较工作区和暂存区之间的差异
- 红色表示删除的内容
- 绿色表示新增的内容
git diff HEAD
:比较工作区和版本库之间的差异git diff cached
或git diff staged
:比较暂存区和版本库之间的差异git diff [id1] [id2]
:根据提交 ID 比较指定的两个版本之间的差异- 当其中一个 id 改为
HEAD
时表示将与最新提交的版本进行差异比较 git diff HEAD~ HEAD
或git diff HEAD^ HEAD
:比较最新两个版本之间的差异
- 当其中一个 id 改为
git diff [name] [name]
:根据分支名比较指定的两个分支之间的差异
0x08 删除文件
-
方法一:
- 首先删除工作区中的文件:
rm file.txt
- 之后更新暂存区中的文件:
git add .
- 最后向版本库提交:
git commit -m "delete file.txt"
- 使用命令
git ls-files
查看暂存区中的文件
- 使用命令
- 首先删除工作区中的文件:
-
方法二:使用命令
git rm
删除文件- 首先从暂存区删除 file.txt 文件:
git rm file.txt
- 最后向版本库提交:
git commit -m "delete file.txt"
- 首先从暂存区删除 file.txt 文件:
-
其他删除操作
git rm --cached file.txt
:仅删除暂存区中的 file.txtgit rm -r *
:递归删除某个目录下的所有子目录和文件
0x09 .gitignore 忽略文件
-
ignore 的意思是 忽略
-
此文件用于让开发者忽略一些不应该加入版本库中的文件,使仓库体积更小、更干净
-
忽略规则:
举例:忽略 *.class, *.0, *.env, *.zip, *.tar, *.pem, *.log 等文件和空文件夹
- 系统或者软件自动生成的文件
- 编译产生的中间文件和结果文件
- 系统运行过程中生成的日志文件、缓存文件、临时文件
- 涉及身份、密码、口令、密钥等敏感信息文件
-
匹配规则
从上到下逐行匹配,每一行表示一个忽略模式
- 空行或以
#
开头的行会被 Git 忽略- 空行一般用于可读性的分隔
#
用作注释
- 使用标准的 glob 模式匹配
*
通配任意字符?
匹配单个字符[]
匹配其中的单个字符
- 使用
**
匹配任意的中间目录 - 中括号可以使用短中线连接
[0-9]
匹配 0 到 9 之间任意的字符
!
表示取反
- 空行或以
-
Github 上有关模板,链接
0x0A GitHub 注册与使用
- GitHub 是一个非常流行的代码托管平台,网站地址
- 点击
Sign up
进入注册界面,依次输入邮箱地址、密码、用户昵称、是否接收邮件推送,完成人机验证,点击create account
,输入邮箱验证号码即可完成注册
0x0B SSH 配置和克隆仓库
(1)GitHub 远程仓库
-
在 GitHub 创建仓库
- 点击 Create repository
- 填写仓库名称、仓库描述(选填)、选择私密性(默认公开)、选择是否初始化一个 README.md 文件、选择是否添加 .gitignore 文件、选择开源许可证文件(可选)
- 点击 Create repository 即可完成仓库创建
-
将本地仓库与 GitHub 远程仓库关联起来
-
方法一:创建并关联新的本地仓库
echo "# [reponame]" >> README.md git init git add README.md git commit -m "first commit" git branch -M main git remote add origin git@github.com:[username]/[reponame].git git push -u origin main
-
方法二:关联已有的 Git 本地仓库
git remote add origin git@github.com:[username]/[reponame].git git branch -M main git push -u origin main
-
方法三:关联已有的其他本地仓库
-
-
远程仓库地址:HTTPS / SSH
-
区别:使用 HTTPS push 到远程仓库时需要验证账密,而 SSH 不需要,但需要配置公钥
2021 年 8 月 13 日起,HTTPS 方法被停用
-
使用 SSH 方式必须配置 SSH 密钥
-
(2)配置 SSH
Linux 环境下为例,点此获取 Windows 环境配置方法
-
进入 .ssh 目录
-
使用命令
ssh-keygen -t rsa -b 4096
生成公钥和私钥 -
使用命令
cat id_rsa.pub
打开公钥文件并复制其中所有内容 -
进入以下页面
graph LR GitHub-->setting -->A(SSH and GPG keys) -->B(new SSH keys)- Title 输入任意内容
- Key type 选择 Authentication Key
- Key 中输入复制的公钥
- 点击 Add SSH key
-
如果生成的密钥未使用默认名称,则需要执行以下命令
tail -5 config # github Host github.com HostName github.com PreferredAuthentications publickey IdentityFile ~/.ssh/[name]
(3)克隆仓库
- 使用命令
git clone git@github.com:[username]/[reponame].git
克隆远程仓库- username:填写用户名称
- reponame:填写仓库名称
- 如果配置 SSH 密钥时设置了密码,则执行上述命令后还需要输入密钥的密码
- 使用以下命令来同步本地仓库和远程仓库的修改内容
- 使用命令
git pull
把远程仓库的修改拉取到本地仓库git pull <远程仓库名> <远程分支名>:<本地分支名>
git fetch
与git pull
的区别在于 fetch 仅获取远程仓库的修改,但并不会自动合并到本地仓库
- 使用命令
git push
把本地仓库的修改推送到远程仓库
- 使用命令
0x0C 关联本地与远程仓库
- 操作命令
- 使用命令
git remote -v
仓库远程仓库
0x0D Gitee 的使用和 GitLab 本地化部署
0x0E GUI 工具
- Git GUI
- GitHub Desktop
- 适用于使用 GitHub 频繁且功能要求不高的情况
- Sourcetree 与 GitKraken
- 适用于对功能要求很高的情况
- ……
0x0F 在 VSCode 中使用 Git
- 可以在 VSCode 自带的“源代码管理”中使用 Git
- 文件状态缩略表示
??
:Untracked,未跟踪M
:Modified,已修改A
:Added,已添加暂存D
:Deleted,已删除R
:Renamed,重命名U
:Updated,已更新未合并
0x10 分支简介和基本操作
- 分支(Branch)是 Git 中一个非常重要的功能,可以看作代码库中的不同版本,可以独立存在并且有自己的提交记录
- 应用场景:团队协作和开发管理
- 使用命令
git branch
查看当前仓库的所有分支- 默认分支为 main
- 创建 temp 分支:
git branch temp
- 删除 temp 分支:
git branch -D temp
-D
:强行删除分支-d
:删除已经完成合并的分支
- 使用命令
git checkout
- 切换到 temp 分支:
git checkout temp
- 此命令既可以切换分支和状态,也可以用来恢复文件或目录到之前的某个状态
- 当分支名称和文件名称相同时,此命令默认执行切换分支操作
- 为解决此问题,可以使用专门切换分支的命令:
git switch
- 切换到 temp 分支:
- 使用命令
git switch
切换分支- 切换到 temp 分支:
git switch temp
- 切换到 temp 分支:
- 使用命令
git merge
将不同的分支合并到当前分支- 在 main 分支中,将 temp 分支并入:
git merge temp
- 终止合并:
git merge --abort
- 在 main 分支中,将 temp 分支并入:
- 使用命令
git log --graph --oneline --decorate --all
查看分支图- 为简化输入,可使用以下命令为其添加别名
graph
:
alias graph="git log --graph --oneline --decorate --all"
,
此后可以使用命令graph
代替
- 为简化输入,可使用以下命令为其添加别名
0x11 解决合并冲突
- 合并冲突:如果两条分支均对某段相同代码进行了不同的修改,则合并时就会产生冲突
- 解决方法:使用命令
git diff
查看冲突位置,做修改后重新提交,再次合并
0x12 回退和 rebase
-
rebase,译为“变基”,其过程类似嫁接
-
使用命令
git rebase
完成变基原分支结构:
graph LR main1-->A(main2) -->main3 -->main4 A-->temp1 -->temp2-
将 temp 分支变基到 main 上:
git switch temp git rebase main
此时分支结构:
graph LR main1-->main2 -->main3 -->main4 -->temp1 -->temp2 -
将 main 变基到 temp 分支:
git switch main git rebase temp
此时分支结构:
graph LR main1-->main2 -->temp1 -->temp2 -->main3 -->main4
-
-
使用命令
git reset
使仓库回退到某个时间点- 回退到 SHA 为 123 的时间点:
git reset --hard 123
- 回退到 SHA 为 123 的时间点:
-
Merge 和 Rebase 的比较
- Merge
- 优点:不会破坏原分支的提交记录,便于回溯和查看
- 缺点:会产生额外提交节点,分支图复杂
- Rebase
- 优点:不会新增额外的提交记录,形成线性历史,直观且整洁
- 缺点:会改变提交历史和当前分支 branch out 的节点,需要避免在共享分支中使用
- Merge
0x13 分支管理和工作流模型
- 工作流模型:使工作更高效、更有条理的规范和流程
- GitFlow 模型
- 分支命名:推荐使用带有意义的描述性名称命名
- 版本发布分支:v1.0.0
- 根据版本号命名
- 功能性分支:feature-login-page
- 根据功能和任务命名
- 修补分支:hotfix-#issueid-desc
- 根据问题编号与简易描述命名
- 版本发布分支:v1.0.0
- 分支管理:
- 定期合并已经成功验证的分支,及时删除已经合并的分支
- 保持合适的分支数量
- 为分支设置合适的管理权限
-End-