分布式版本控制工具Git的安装与使用
命令速查
更多命令可见菜鸟教程
Git简介
为什么要使用git
真实生产环境中,代码通常由多人、甚至多个部门协作开发。如果靠 U 盘拷贝、手动合并代码,不仅效率极低,还极易出现代码覆盖、丢失、冲突等问题。因此,需要一套可靠的版本控制工具来管理代码,Git 正是当下最主流的解决方案。
Git 是分布式版本控制工具(Distributed Version Control System),与传统集中式版本控制工具,如 SVN有本质区别:
- 集中式工具高度依赖中央服务器,开发者从服务器拉取代码,修改后再提交回服务器。一旦服务器宕机、或开发者网络异常,就无法正常协作与提交;
- 分布式的 Git 让每个开发者本地都拥有完整的版本库,不依赖单一中央服务器,从根本上解决了单点故障和网络限制问题。
详细作用可见为什么程序员都要用git,Git能实现的功能主要如下:
- 版本回滚:git记录项目每次修改,新版本带来的问题可立即回滚为以往版本减小损失;
- 并行开发:多个开发者可在不同分支开发,git会智能合并各自的部分,多人合作可通过远程仓库获取资源,让协作变得更高效;
- 溯源:git会记录每次修改的说明和作者,避免bug扯皮;
- 数据安全:git将代码存储到个人仓库的分布式特性保证项目几乎永远不会丢失。
下载与安装
官网链接:https://git-scm.com/
有关安装详细说明可见Git详细安装教程,还有选项涉及到黑命贵(master不尊重黑人要改成main???),这里一路next安装,右键菜单出现如下界面说明安装成功:
也可以在cmd窗口中使用git -v命令查看版本,本次安装的是最新的2.53.0,提示如下:
C:\Users\hp>git -v git version 2.53.0.windows.1 使用方法
git的工作原理
git根据代码位置将存储划分为四个区域,分别为工作区、暂存区、本地仓库和远程仓库。
- 工作区(Working Directory):工作区是开发代码的目录,也就是实际代码存放的文件夹,修改后的代码文件使用
git add提交到暂存区; - 暂存区(Staging Area):暂存区是一个临时保存的区域,保存了准备提交到仓库中的所有改动,为
.git目录下的二进制文件,通过git commit提交到本地仓库;
暂存区给开发者提供了更细粒度的控制手段。一次修改可能包含多个不同内容的修复,暂存区分批提交可以细化提交工作。
- 本地仓库(Local Repository):存储在本地机器上的 Git 仓库,记录了项目的所有提交历史。可用命令有:
git merge 分支名合并其他分支的代码到当前分支、git checkout 分支名切换到指定分支; - 远程仓库(Remote Repository):位于服务器端的远程仓库,如github、国内的gitee(码云)和需要自己部署的gitlab,常用命令有
git push本地仓库推送至远程服务器git clone远程仓库克隆到本地,通常只有第一次使用git fetch从远程服务器获取修改到跟踪分支,后续手动使用git merge合并git pull从远程服务器获取修改并自动合并,即pull=fetch+merge
相关流程可表示为下图:
本地命令
- 状态转换
配置别名
我们要使用的有些命令较长,可以采用起别名的方法简化,新建.bashrc文件,写入alias 新命令 '原长命令',并使用source .bashrc编译即可,别名alias ll='ls -al'的示例如下:
配置用户信息git config --global user.name 用户名指定全局用户名git config --global user.email 邮箱指定全局邮箱git config --global user.name查看用户名git config --list查看所有配置
初始化仓库
要使用的目录下右键进入git bash,输入命令git init,可见生成隐藏目录.git
| 命令 | 含义 |
|---|---|
| git status | 查看文件状态 |
| git add 文件名/通配符 | 工作区添加至暂存区,.表示目录所有 |
| git commit -m “注释” | 暂存区提交至本地仓库,可添加说明 |
| git log | 查看日志,–graph展示分支 |
| git reset --hard commitID | 回滚到以前版本,id在log,通常取前七位 |
| git reflog | 查看所有提交记录,用于回滚的二次反悔 |
- 忽略文件
有些文件我们不希望参与git管理,可新建.gitignore文件,文件内写通配符或具体名称即可,如*.a为以a为扩展名结尾的文件不参与管理。
远程仓库
- 远程操作仓库
git clone 仓库路径 本地目录,首次使用仓库需克隆,本地目录缺省会直接使用仓库名称新建,克隆包含所有分支的完整仓库,需特定分支可用参数-b 分支名指定;git fetch origin 分支名,抓取更新文件到远程跟踪分支git merge,合并更新至当前所在分支git pull origin 分支名,拉取并合并,等于fetch+mergegit push origin 分支名,将本地分支上传到仓库,有则合并(本地分支落后时拒绝),无则创建git branch查看分支
分支保护
master是开发的主分支,各组件开发、功能修复等分支最后都往这个分支合并,必须对这个分支进行保护,可使用如下权限设置。
主分支的合并需要审核和测试才能进行。
远程连接
ssh连接远程仓库需使用密钥,先使用ssh-keygen -t rsa生成rsa密钥,三次回车全选默认配置(第一次选项是换目录,换了会导致后续无法验证,要换目录验证时可用-i指定),图中是密钥保存位置。
Linux可使用cat打开,Windows找到对应目录自行打开,复制id_rsa.pub的密钥添加公钥。
使用 ssh -T [email protected]验证连接,出现如下界面说明密钥配置成功:
git remote add origin 地址添加远程仓库,仓库名为origin
新建仓库
国内使用比较方便的代码平台是码云,官网为https://gitee.com,网页右上角,头像旁按键可新建仓库。
新建后选择仓库名称和介绍
随后生成初始化readme
解决冲突
不同开发者更改了代码的相同几行即为冲突,如二者都根据登录模块同时添加功能,第一个提交者在行末添加,第二个开发者要提交时则会报冲突。
比如两个用户分别修改如下行:
A用户上传成功,B用户要上传会提示错误,提示本地没有文件,本质是远程版本比本地的更新(更新基线问题),git会自动拒绝对更新版本的覆写。
此时需要先使用git pull拉取最新版本,在本地解决冲突,冲突行git会标记提示,此时需要开发者自行解决,通常是挪动代码。
冲突标记包围的上方是待推送内容,下方是远程仓库拉取的最新内容,最下方的1是误报,删除标记整合重新提交即可。
gitadd 文件名 git commit -m"解决冲突:保留用户B前两行,下方1内容无差异"git push origin master 扩展
git的智能合并
Git 保障合并操作安全的核心前提是合并双方拥有共同的提交基线(相同起点)。若本地分支与远程分支的基线不一致(本地落后于远程),Git 会要求先执行git pull同步远程最新内容,再进行本地提交和推送 ,这一机制能从根本上避免本地修改覆盖远程最新提交记录的风险。
需要注意的是,分支基线的同步状态依赖 Git 对提交历史的追踪:执行git pull后,本地分支的提交基线会与远程仓库保持一致;而本地执行git commit后,Git 会更新本地分支的提交历史记录,形成新的基线状态。
git的管理边界
git支持纯文本文件,可以实现冲突检测功能,但以TSV 结构化文本为例,Git 能识别并标记文件中发生修改的行,但无法感知行内列级别的数值变化,需手动定位和解决列级差异。
同时经过测试,图像、exe等二进制文件也可使用git进行管理,但git无法检测具体变化,每次更新只能全部覆盖,对二进制文件的管理效率低,开销大。
存储问题
git记录提交状态并可以随时恢复的功能十分强大,但保存如此多的状态是否可能导致存储压力过大。
我修改了一个17字节的文件,但.git文件夹内却有17KB的内容,那100MB的文件修改10次,其保存的状态文件会不会是1000MB呢?这是不会发生的,git底层只存储变化的内容,无变化的内容复用,具体原因为:
- 文本文件复用:Git记录行级别差异,修改一行数据,只存储该行的修改记录加少量元数据。
- 二进制文件压缩快照:根据哈希值判断是否修改,git无法识别二进制文件的具体差异,git会存储变化文件的压缩快照,这也是为什么使用git管理二进制文件较为低效。
此外git还有垃圾回收机制,和专门针对大文件的管理程序git lfs。