参考资料:b 站 up 停止重构;菜鸟教程:Git 教程 | 菜鸟教程 (runoob.com)
基本定义
- Git 是存储文件的仓库,集中存储在服务器
- 用户可上传文件到仓库,也可下载文件副本到本地磁盘
- 文件类型不受限制,可以是文本、图片、视频等文件
Git服务并不是单纯地存储,它有版本管理的功能
Git服务会记录每一次修改历史,用户可翻看历史版本或还原文件
1. 版本管理的作用:
- 历史记录:可随时翻看历史修改,复原不正确的修改
- 跟踪记录:跟踪记录项目版本迭代过程,方便旧版本回滚、抽离
- 保持文件一致性:帮助团队并行开发
2. Git优势:
Git 支持分布式部署
Git 是按元数据存储的,存储空间相对少一些
Git 可选择功能更加丰富的平台服务,如 GitHub、Gitlab
3. Git、GitHub、Gitlab 的区别与使用
- Git 是系统核心,没有界面,只包含基础功能
- GitHub、Gitlab 是在 Git 基础上建设的远程平台,包含 Git 服务,拥有更加完善的后台管理网站,拥有更加丰富的扩展功能,包括项目管理、版本视图、权限管理等
- Git 服务功能简单,一般不直接使用或部署 Git 服务
- 一般选择功能更加丰富的 GitHub、Gitlab 平台
- Gitlab 支持私有化部署
服务原理:
Git 是客户端-服务端架构服务
1. 远程服务:
1.1. 远程平台
远程服务器的一个文件夹的库,远程服务是 Git 的服务端,它可以是 Gitlab 或者 GitHub 等远程平台,同时也可以是自己在 docker 中搭建的 Gitlab 平台
1.2. 远程仓库
在远程平台中,文件主要以远程仓库为单位来存储文件
仓库可以简单理解为文件夹,一个仓库中可以存储多个文件、创建多级文件夹目录。
仓库中存储的文件不受限制,可以是文本文件、媒体文件等。
2. 本地平台:
2.1. 本地仓库
本地仓库副本对应一个远程仓库,其实际为本地磁盘的某一个文件夹,是远程仓库的一个克隆副本,文件夹内的文件对应远程仓库的文件,可以对文件自由操作。
在进行本地仓库副本的获取时,首先用户需要通过本地 Git 客户端与远程服务通信。
本地仓库副本的获取、更新上传都需要通过本地 Git 客户端进行操作。一般都是通过命令行来使用 Git 工具。
在本地仓库副本的文件夹中存在一个.git 的隐藏文件夹,该文件夹内内容是用于记录远程仓库信息、日志、未提交远程仓库的记录等信息。
Git 的安装
1. Git 服务端的安装:
1.1. docker 私有部署 Gitlab:
下载 Gitlab 镜像:
docker pull gitlab/gitlab-ce
启动 Gitlab 容器:
docker run --detach \
--publish 80:80 \
--name gitlab \
--restartalways \
-e TZ="Asia/Shanghai" \
gitlab/gitlab-ce
部署结束,使用服务器 IP 打开管理网站
1.2. 其他方法
也可以直接使用对应平台的网站进行管理,如 Gitlab 网站(国内使用 jihulab),GitHub 客户端
同时也可以使用 GitHub,详见:Git 远程仓库(Github) | 菜鸟教程 (runoob.com)
可以将 Gitlab 部署安装到本地:Git 服务器搭建 | 菜鸟教程 (runoob.com)
2. Git 本地化部署:
2.1. Git 客户端安装:
Git 客户端软件一般是命令行工具
Ubuntu/Debian 系统:
sudo apt install git-all
CentOS系统:
yum install git
MacOS 系统(先安装 Homebrew):
brewinstall git `
Windwos 系统:下载 Git for Windows
检查安装是否成功:
git --version
除此之外,对于 windows 和 Mac 系统而言,Git 还有一些具有图形操作界面的客户端软件如 GitHub 客户端和 Fork。
一些 IDE,比如 vscode 也集成了 Git 客户端。
Git 常用操作
1. 远程仓库操作
1.1. 新建管理远程仓库
新建和管理远程仓库一般在 Git 服务的后台管理网页完成
以 Gitlab 举例:
1.2. 远程仓库管理:
远程仓库管理,需要关注修改记录、分支、tag、权限
Gitlab 仓库管理页面
1.2.1. 修改记录
修改记录是每次上传更新的记录,一个修改记录可能包含多个文件的修改
每个修改记录对应唯一的修改记录 id
回滚操作实际上是新提交一次更新以复原修改
当回滚的修改记录不是文件的最新修改记录则会由于修改冲突而失败此种情况需要人工修改再提交
1.2.2. 分支
1.2.2.1. 分支概念
分支是一个远程仓库内的多个独立副本
每个分支都是完全独立互不影响的
文件、修改记录都是单独存储的
1.2.2.2. 创建新分支
一个仓库默认有一个主分支默认将文件存储到主分支
创建新分支基于某个修改记录、某个分支、某个 tag
1.2.2.3. 分支合并
一个分支的多次修改可一次性更新到别的分支,称为合并(merge)
实际上是对目标分支提交一次新修改
但是可能会由于修改冲突而失败(目标分支也修改了相同文件)此种情况需要人工修改更新到目标分支
1.2.3. tag
tag 是一个标识,不允许更新文件
分支是独立副本,允许更新文件
1.2.4. 权限
2. 本地操作:
- workspace:工作区
- staging area:暂存区/缓存区
- local repository:版本库或本地仓库
- remote repository:远程仓库
2.1. 一些基本命令
2.1.1. 创建仓库命令
命令 | 说明 |
---|---|
git init | 初始化仓库 |
git clone | 拷贝一份远程仓库,也就是下载一个项目。 |
2.1.2. 提交与修改
Git 的工作就是创建和保存你的项目的快照及与之后的快照进行对比。
命令 | 说明 |
---|---|
git add | 添加文件到暂存区 |
git status | 查看仓库当前的状态,显示有变更的文件。 |
git diff | 比较文件的不同,即暂存区和工作区的差异。 |
git difftool | 使用外部差异工具查看和比较文件的更改。 |
git range-diff | 比较两个提交范围之间的差异。 |
git commit | 提交暂存区到本地仓库。 |
git reset | 回退版本。 |
git rm | 将文件从暂存区和工作区中删除。 |
git mv | 移动或重命名工作区文件。 |
git notes | 添加注释。 |
git checkout | 分支切换。 |
git switch | 更清晰地切换分支。 |
git restore | 恢复或撤销文件的更改。 |
git show | 显示 Git 对象的详细信息。 |
2.1.3. 提交日志
命令 | 说明 |
---|---|
git log | 查看历史提交记录 |
git blame |
以列表形式查看指定文件的历史修改记录 |
git shortlog | 生成简洁的提交日志摘要 |
git describe | 生成一个可读的字符串,该字符串基于 Git 的标签系统来描述当前的提交 |
2.1.4. 远程操作
命令 | 说明 |
---|---|
git remote | 远程仓库操作 |
git fetch | 从远程获取代码库 |
git pull | 下载远程代码并合并(更新本地仓库) |
git push | 上传远程代码并合并(更新远程仓库) |
git submodule | 管理包含其他 Git 仓库的项目 |
2.2. 初始化仓库:git init
Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令。
在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。
2.2.1. 创建步骤
创建新的目录
mkdir my-project
cd my-project
使用当前目录作为 Git 仓库
git init
使用指定目录作为 Git 仓库
git init <name>
2.3. 克隆:git clone
2.3.1. 克隆远程仓库
克隆远程仓库,将远程仓库文件克隆到本地仓库副本
克隆命令:
git clone [http 克隆地址][指定目录],克隆地址和指定目录复制远程仓库中的克隆地址即可
注意,远程仓库也可以直接下载文件,但是这样的文件无法进行版本控制。
2.3.2. 克隆指定分支:
如果需要使用一个远程仓库的多个分支的代码
推荐克隆多个本地仓库副本
克隆指定分支的命令:gitclone--branch[目标分支名][http 克隆地址][指定目录]
2.4. 分支:
Git 分支管理是 Git 强大功能之一,能够让多个开发人员并行工作,开发新功能、修复 bug 或进行实验,而不会影响主代码库。
几乎每一种版本控制系统都以某种形式支持分支,一个分支代表一条独立的开发线。
使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。
2.4.1. 创建分支:
git checkout -b <branchname>
git branch <branchname>
2.4.2. 查看分支
查看本地所有分支:
git branch
查看远程分支:
git branch -r
查看所有分支;
git branch -a
2.4.3. 切换分支:
git checkout (branchname)
2.4.4. 合并分支:
git merge <branchname>
当合并过程中出现冲突时,Git 会标记冲突文件,你需要手动解决冲突。
打开冲突文件,按照标记解决冲突。
标记冲突解决完成:
git add <conflict-file>
提交合并结果:
git commit
2.4.5. 删除分支
删除本地分支:
git branch -d <branchname>
强制删除未合并的分支:
git branch -D <branchname>
删除远程分支:
git push origin --delete <branchname>
2.5. 标签:
如果达到一个重要的阶段,并希望永远记住提交的快照,可以使用 git tag
给它打上标签。
Git 标签(Tag)用于给仓库中的特定提交点加上标记,通常用于发布版本(如 v1.0, v2.0)
2.5.1. 打标签
标签语法格式为:
git tag <tagname>
-a 选项可以添加注解,
2.5.2. 查看所有标签
git tag
2.5.3. 推送标签到远程仓库
默认情况下,git push 不会推送标签,需要显式地推送标签。
git push origin <tagname>
推送所有标签:
git push origin --tags
2.5.4. 删除轻量标签
本地删除:
git tag -d <tagname>
远程删除:
git push origin --delete <tagname>
2.5.5. 附注标签
附注标签存储了创建者的名字、电子邮件、日期,并且可以包含标签信息。附注标签更为正式,适用于需要额外元数据的场景。
创建附注标签语法:
git tag -a <tagname> -m "message"
例如:
git tag -a <tagname> -m "runoob.com标签"
PGP 签名标签命令:
git tag -s <tagname> -m "runoob.com标签"
查看标签信息:
git show <tagname>
2.6. 上传操作
对本地仓库副本中的文件修改完成后,需要手动上传到远程仓库才能同步
上传操作一般分为 3 步:
- 添加文件到暂存区
- 提交暂存区到本地仓库
- 上传远程仓库
2.6.1. 添加文件到暂存区:
提交文件到缓存区,是指选定哪些被修改的文件为此次上传的内容
cd[目标仓库副本目录]
查看被修改的文件列表:gitstatus
提交文件到缓存区:git add[文件 1][文件 2]
提交全部文件到缓存区:git add *
查看具体文件修改内容:git diff[文件]
git status
git add filenames
git diff filename
2.6.1.1. 注意
Git 认为空文件夹是无效的,不会提交
需要在空文件夹里添加.gitkeep 文件
其他名字的文件也可以,文件夹不空就行
Git 对文件名的大小写不敏感
将文件名从 config 改成 CONFIG,Git 不认为这是一次更新
需要用户手动删除文件并上传同步后,再重新添加文件再上传同步
2.6.2. 提交本地仓库:
2.6.2.1. 填写更新日志
提交本地仓库,将暂存区的修改内容打包成一次更新
提交本地仓库需要填写更新日志
git commit -m "日志名称+日志内容"
提交本地修改,不会同步到远程仓库
只记录会将修改记录在本地仓库副本的.git 文件夹中
用户可多次添加文件到暂存区-提交本地仓库
以根据不同修改目的
记录多次更新,填写多个更新日志
2.6.3. 上传远程仓库:
2.6.3.1. 同步到远程仓库
提交远程仓库,将本地仓库的修改同步到远程仓库
可一次性将多次本地仓库修改同步到远程仓库
git push
2.6.3.2. 推送到指定的分支:
推送到指定远程分支:git push origin 本地分支:远程分支
推送本地分支到同名远程分支:`git push origin 分支名
强制推送(覆盖远程分支):git push --force origin 分支名
设置默认推送分支:git push --set-upstream origin 分支名
- 列出所有本地分支:
git branch
- 查看当前所在分支:
git branch --show-current
或git rev-parse --abbrev-ref HEAD
2.6.4. 撤销本地仓库提交
上传远程仓库,要求本地仓库副本为远程仓库最新版本
如果没有更新冲突,则再次提交即可
如果发生更新冲突,恰巧本地修改的文件在远程仓库中也被修改了
- 撤销本地仓库提交,git 命令行工具示例:git reset origin
- 解决更新冲突
- 再重新提交上传
可以忽略更新冲突,强制上传远程仓库 (非常不推荐)
但这样会造成更新覆盖,造成团队代码覆盖,把别人代码弄没了
git push --force
2.6.5. 上传现有的仓库到 Gitlab
cd <仓库名>
git remote rename 原项目名 想修改成的项目名
git remote add 原项目名 <ssh链接>
git push -u 现项目名 <分支名,一般为main >
2.7. 冲突与解决:
在进行分支的合并、本地仓库的更新等操作时,容易出现由于两边同一文件同时出现修改所造成的冲突问题,此时则需要解决该冲突。
2.7.1. 解决方法 1
命令行工具示例
cd[目标仓库副本目录]
暂存本地修改:git stash
更新:git pull
恢复本地修改:git stash pop
更新冲突的内容会在文件中标记出来
(后续需要人工处理)
2.7.2. 解决方法 2
更新冲突别的解决方案
克隆一份新的本地仓库副本
通过 beyondcompare 等工具对比差异文件
再人工修改这些差异内容
2.7.3. 小结
无论是哪一种方法,都需要最后对差异问题进行人工的修改
实际项目中使用 Git
1. 代码管理存在问题
1.1. 多环境代码管理
一般项目都有开发环境、测试环境、生产环境等
每个环境对应不同的代码.
理想情况下,多环境代码是顺序更新的
实际情况下,多环境代码是不一定是顺序更新的
1.2. 多版本代码管理
多版本指的是需要同时维护的多个版本的代码
- 软件存在几个 lts 版本(长时间支持版本)需要维护
- 软件存在 lite 版本、专业版、旗舰版
多版本代码一般是完全独立的,每个版本有各自的迭代计划
但一些时候可能会有一些联动,如修改基础 BUG、功能移植等
1.3. 多人协同开发
多人参与一份代码开发,经常会发生更新冲突
处理更新冲突一般需要人工处理,很耗时间
1.4. 日志规范
Git 是用于记录变化,方使日后翻查记录
而日志是翻看时很重要的标识
如果更新日志是胡乱写的话,则日后翻看会非常艰难
如 11 月 20 日 bug 更新、更新 bug 等
2. 多环境代码管理
一般情况下,按照一个迭代周期
开发分支、测试分支、生产分支代码是顺序合并的
一个 Git 仓库分支的多次修改可一次性更新到别的分支,称为合并(merge)
顺序流程的代码分支合并是简单的
因为不会出现修改冲突
一个迭代周期结束后
对生产分支创建新 tag,以方便日后查看
tag 是一个标识,用于标记基于某个修改记录
当前迭代周期的测试阶段开始时,下一迭代周期的开发阶段会同步开始
生产环境发现 BUG
如果不太严重
建议作为下一迭代周期的任务,这样可以不打乱计划
3. 多版本代码管理
工作安排上需要预留多版本同步修改的时间
多版本修改并不是简单的代码合并
很多时候都需要花时间判断修改内容,如何修改