目录

git 应用总结与提高

前言

Git 是一款由 Linus Torvalds(Linux 内核创始人)于 2005 年开发的 分布式版本控制系统(Version Control System,VCS),核心目标是高效管理代码的版本迭代与多人协作开发,现已成为全球最流行的代码管理工具(广泛搭配 GitHub、GitLab、Gitee 等远程仓库平台使用)。

安装

1、安装 Git

Git 是一款开源分布式版本控制系统,核心特性为分布式架构与版本全量追踪,支持本地独立完成开发工作,仅需在同步协作时联网。直接访问 Git 官方下载页面,下载对应系统版本的安装包,双击运行一路默认安装即可。

Git 的打开步骤(先右键点击文件区空白处):

../img/20190118_001.jpg

点击展开内容【常见的代码托管网站】

1)国际主流平台

网站名称 网址 核心特点
GitHub https://github.com 全球最大的代码托管与开源协作平台,支持 Git 版本控制,托管了海量开源项目。免费版可创建私有和公有仓库,适合个人开发者、开源社区及企业,仅国内访问偶尔不稳定。
GitLab https://gitlab.com 开源的代码托管平台,支持 DevOps 全生命周期流程。免费版可创建无限个私有和公有仓库,每月提供 400 分钟 CI/CD 构建时长,还支持企业搭建私有部署版本,适配大型团队协作。
SourceForge https://sourceforge.net 老牌开源项目托管平台,历史悠久。除了 Git,也支持 SVN 和 Mercurial。提供文件下载、项目统计等传统功能。
Bitbucket https://bitbucket.org 支持 Git 和 Mercurial 两种版本控制工具。免费版适合小型团队,支持 5 人以内团队创建无限私有仓库,功能上与 GitHub 相近,侧重团队协作中的代码托管和基础协作需求。
Codeberg https://codeberg.org 由欧盟开发者维护,基于 Gitea 搭建,注重隐私保护和开源精神。平台免费且无广告,适合追求数据安全和轻量化代码托管的用户,国内访问速度尚可。
Framagit https://framagit.org 法国公司运营,基于 GitLab 搭建,服务器位于德国。支持代码托管和基础协作功能,适合对欧洲服务器访问需求较高的开发者,整体访问稳定性较好。

2) 国内主流平台

网站名称 网址 核心特点
码云
Gitee
https://gitee.com 国内最常用的代码托管平台,服务器在国内,访问速度快、稳定性高。免费版支持无限个私有和公有仓库,单个团队限 5 名成员,适合个人、小团队及国内企业的项目托管,还提供代码迁移、在线编辑等适配国内开发者的功能。
阿里云效
Codeup
https://codeup.aliyun.com 阿里云推出的企业级代码管理平台,是阿里老版 Code 的升级版本。免费版不限人数,提供 100GB 托管总容量,支持代码评审、质量检测、CI/CD 等 DevOps 功能,适配企业级研发协作场景。
CODING https://coding.net 侧重研发协作的代码托管平台,免费版提供 100GB 总仓库容量,不限团队人数。除代码托管外,还集成了项目协同、制品库、流水线等功能,能满足中小团队到企业级的研发全流程需求。
腾讯工蜂 https://git.code.tencent.com 腾讯推出的纯代码托管平台,支持 Git 版本控制,不限用户数和组织个数,适合腾讯生态内的开发者及企业,侧重代码的基础托管和团队协同管理。
极狐
JihuLab
https://jihulab.com GitLab 的中国版,功能与 GitLab 对齐。免费版支持无限私有和公有仓库,每月 400 分钟 CI/CD 流水线时间,每个项目仓库容量 2GB,适配国内企业的 DevOps 协作需求,访问速度和稳定性更贴合国内网络环境。
   
2、安装可视化辅助工具

TortoiseGit 是一款开源版本控制客户端,其源代码托管于 GitLab。你可以直接访问 TortoiseGit 官方下载页面,获取对应版本的软件安装包与语言包:例如 64 位系统适配的 TortoiseGit-2.13.0.1-64bit.msi 主程序,以及配套的 TortoiseGit-LanguagePack-2.13.0.0-64bit-zh_CN.msi 中文语言包。安装时请先运行软件包,再安装语言包,以确保语言配置生效。

TortoiseGit 中文界面设置步骤(先右键点击文件区空白处):

../img/20190118_002.jpg

TortoiseGit 支持为文件及文件夹配置图标叠加标记,帮助开发者快速识别代码的变更情况:

../img/20190118_003.jpg

PS:借助 TortoiseGit 可视化工具开展代码对比工作,既能显著提升操作效率与比对准确性,又可直观查看工作区的代码修改情况,大幅降低人工比对的成本与误差。

3、设置邮箱地址和用户名

第一次安装 Git 后,通常需要做的第一件事就是设置邮箱地址和用户名,它们是你在 Git 世界里的 “身份证”。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#-------设置全局邮箱地址和用户名-------
git config --global user.email "o2o@qq.com"  #【重置】全局邮箱地址(--global 表示设置全局参数。当不加此选项时,表示对象是当前所在仓库参数)
git config --global user.name "o2ospring"    #【重置】全局用户名 (--global 表示设置全局参数。当不加此选项时,表示对象是当前所在仓库参数)

#git config --global user.email              #【查看】全局邮箱地址(--global 表示设置全局参数。当不加此选项时,表示对象是当前所在仓库参数)
#git config --global user.name               #【查看】全局用户名 (--global 表示设置全局参数。当不加此选项时,表示对象是当前所在仓库参数)
#git config --global -l                      #【查看】全局配置参数(--global 表示设置全局参数。当不加此选项时,表示对象是当前所在仓库参数)
#git config --global --edit                  #【编辑】全局配置参数(--global 表示设置全局参数。当不加此选项时,表示对象是当前所在仓库参数)
#git config --global credential.helper cache #【缓存】用户名和密码(当频繁通过 HTTPS 操作远程仓库,可避免每次重复输入凭证,除非凭证过期或终端关闭)
#git config --global credential.helper 'cache --timeout=1800'
                                             #【修改】缓存有效期为 30 分钟(默认缓存 15 分钟)

PS:--global配置的参数存在 Windows 的 C:\Users\你的用户名\.gitconfig 或 macOS/Linux 的 ~/.gitconfig 文件中。

使用

01、假设克隆仓库

若仅需对现有工程进行修改,可直接从远程仓库克隆代码至本地;完成本地环境配置与远程仓库关联后,即可按需开展代码修改、调试、提交及推送更新等操作。

1.1、克隆所有分支

当项目仓库包含发布分支(如 release/*)、开发分支(如 develop)等多分支结构时,需克隆完整仓库以支持全流程开发、分支切换与版本迭代。此方式会同步下载所有分支的历史提交记录,会占用更多本地存储空间。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#-------克隆所有分支-------
                                  #【方式一】克隆远程仓库所有分支(SSH 方式)(注意:使用 SSH 克隆之前先要添加 SSH key,具体操作后面再介绍,所以暂不推荐这种方式)
git clone git@github.com:espressif/esp-idf.git
                                  #【方式二】克隆远程仓库所有分支(http方式)(如果忘记拉取子模块,则可以使用 git submodule update --init --recursive 命令补救)
git clone https://github.com/espressif/esp-idf.git
                                  #〖情形二〗当远程仓库有嵌套仓库时,克隆所有分支的同时,同步拉取嵌套仓库
git clone --recursive https://github.com/espressif/esp-idf.git
                                  #〖情形三〗同上,并且将本地工作区自动切换到`release/v5.1`分支(备注:`release/v5.1`是分支名称,`/`仅作为名称字符的一部分)
git clone --recursive -b release/v5.1 https://github.com/espressif/esp-idf.git

#git checkout -b aaaa origin/aaaa # 基于【远程跟踪分支】创建并切换到新的本地分支,同时建立跟踪关系(注:不会从远程仓库拉取数据)(貌似 git checkout aaaa 也会自动处理)
                                  #【远程跟踪分支】:是已从远程仓库同步到本地的分支。例如:克隆整个远程仓库,除当前分支外,其它分支还处于隐藏状态,需要通过上行命令检出
点击展开内容【SSH 密钥添加】

SSH 密钥分公钥和私钥,公钥是 “锁”,私钥是 “钥匙”。客户端生成这对密钥后,把公钥(锁)装到服务器上,之后客户端用私钥(钥匙)就能直接免密登录服务器了。

1)【生成】SSH 加密密钥

1
2
3
4
ssh-keygen -t rsa -C "o2o@qq.com" #【生成】SSH 加密密钥(过程提示【输入文件名】和【输入两次密码】,全部按回车即表示使用默认文件名和不需要密码)
                                  # -t 指定密钥类型,默认是 rsa,可以省略。
                                  # -C 设置注释文字,比如邮箱。 
                                  # 生成的密钥(id_rsa 私钥文件、id_rsa.pub 公钥文件)存在 Windows 的 `C:\Users\你的用户名\.ssh\` 或 macOS/Linux 的 `~/.ssh/` 目录中

2)【添加】SSH key 到托管网站

../img/20190118_008.jpg

PS:GitHub 支持添加多个 SSH Key。如果你需要在多台设备(比如公司电脑和家用电脑)上提交代码,只需将每台设备的 SSH Key 都配置到 GitHub 账号中,就能在任意设备上直接向远程仓库推送代码了。

   

1.2、克隆单个分支

当项目仓库需针对特定功能模块或指定发布版本进行开发,建议直接克隆对应功能分支 / 版本分支,基于该分支迭代开发。此方式可避免拉取全量仓库历史数据,显著降低本地存储占用,同时确保开发环境与目标版本的一致性。

1
2
3
4
5
#-------克隆单个分支-------
                                  #〖情形一〗仅克隆远程仓库中指定的`release/v5.1`分支,不会下载其他任何分支(备注:`release/v5.1`是分支名称,`/`仅作为名称字符的一部分)
git clone --single-branch -b release/v5.1 https://github.com/espressif/esp-idf.git
                                  #〖情形二〗同上,当远程仓库有嵌套仓库时,克隆指定分支的同时,同步拉取嵌套仓库
git clone --recursive --single-branch -b release/v5.1 https://github.com/espressif/esp-idf.git

PS:关于--recursive--recurse-submodules的区别:
 1)--recursive作用对象是【嵌套仓库】(目录下有 .git 的独立仓库)
 2)--recurse-submodules作用对象是【子模块】(通过 .gitmodules 配置的依赖)
 3)目前掌握到信息,两者应该是一样的,但推荐:
   --recurse-submodules 用于 git clone, git pull, git fetch 等命令,表示"在执行此操作时递归处理子模块";
   --recursive 只用于 git submodule 命令本身,表示"递归执行这个子模块操作"。

1.3、设置邮箱地址和用户名

1
2
3
#-------设置当前仓库的邮箱地址和用户名-------
git config user.email "xxx@qq.com"#【设置】当前仓库的邮箱地址(备注:当不单独设置时,将默认使用全局配置的邮箱地址和用户名)
git config user.name "xiaoming"   #【设置】当前仓库的用户名 (备注:当不单独设置时,将默认使用全局配置的邮箱地址和用户名)

PS:建议为此仓库单独设置专属邮箱地址及用户名(未单独设置时,将默认使用全局配置的邮箱地址和用户名),为开发工作做好前置准备!

02、假设新建仓库

若需自行新建工程,需先在远程代码仓库(如 GitHub/GitLab/Gitee)与本地环境分别创建对应仓库,后续再进行代码初始化、分支配置及远程关联操作。

2.1、远程新建

首先在指定平台创建共享远程仓库,为团队成员后续的代码推送、同步及协作开发提供统一的版本管理中心。

../img/20190118_004.jpg

2.2、本地新建

当远程仓库尚未创建,或已创建但为空白仓库,可先在本地初始化 Git 仓库并完成项目代码编写 / 提交,随后通过关联远程仓库地址、设置上游分支,最终执行推送操作将本地代码同步至远程仓库。

1
2
3
4
5
6
7
#-------本地新建仓库-------
git init --initial-branch=main    #【新建】一个空的全新的本地仓库。(git init 不指定名称时,可能是 master,因其有种族歧视性,所以很多厂家改用 main)
git config user.email "xxx@qq.com"#【设置】当前仓库的邮箱地址(备注:当不单独设置时,将默认使用全局配置的邮箱地址和用户名)
git config user.name "xiaoming"   #【设置】当前仓库的用户名 (备注:当不单独设置时,将默认使用全局配置的邮箱地址和用户名)
touch README.md                   #【添加】一个读我文件(一般情况下仓库都应有一个<README.md>文件作为工程的介绍)
git add .                         #【添加】工作区文件到【暂存区】。(可以重复添加多次,也可以添加一个或多个指定文件,如:git add test.c 添加指定文件)
git commit -m "first commit"      #【提交】暂存区文件到【本地库】。(first commit 是提交的文字说明)

2.3、添加过滤

在实际工程场景中,部分文件无需纳入版本管理(尤其各类中间编辑文件,如编译生成的临时文件、编辑器缓存等),通过配置版本控制工具的忽略规则(.gitignore 等)可自动排除这类文件,既能避免冗余数据占用仓库存储空间、减缓仓库拉取 / 推送速度,也能减少版本控制的无效操作,提升协作效率。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#-------添加过滤规则-------
touch .gitignore                  #【创建】一个忽略规则文件
                                  # 使用文本编辑工作添加需要忽略的文件(夹),例如:
                                  # *.o               #忽略 *.o 文件。即 git 不管理当前目录及其下面所有层级的 *.o 文件
                                  # output2/          #忽略 output2 目录。即 git 不管理 output2 这个文件夹,意味着其里面所有内容也被忽略,同时表明它下面文件(夹)不能使用`!`来指定某些文件(夹)解除忽略
                                  # output/*          #忽略 output 目录下的所有文件和目录 -----------\
                                  # !output/abc/      #但是,不要忽略 output/abc/ 这个目录 ----------|--> 配合使用
                                  # !output/abc/**/*  #并且,不要忽略 output/abc/ 目录下的所有内容 --/
                                  #                   #其中,** 表示递归所有子目录,例如包括孙目录。
                                  # 如果不使用文本编辑工具,可以使用命令初始添加忽略规则内容,例如:
#echo -e "*/build/*\n*JLinkLog.txt\n*.o\n*.d\n*.a\n*.i\n*.map\n*.elf\n*.bin\n*.hex\n*.axf\n*.crf\n*.bak\n*.dep\n*.rar\n*.zip\n*.7z" >> .gitignore

2.4、工程构建

在构建规范化工程时,通常会包含若干【标准通用模块】。这类模块可独立抽离至单独仓库进行管理,后续可通过仓库关联机制将这些子仓库整合至工程父仓库中,实现模块复用与统一管控。若此类模块已提前部署至远程仓库,可关联或整合到父仓库,方法如下:

1
2
3
4
5
6
#=======【方式一】关联子仓库〖版本链接〗=======
                                  #【添加】子模块【指定分支】到【指定目录】src/cjson/(会自动创建目录)
git submodule add -b master https://github.com/DaveGamble/cJSON.git src/cjson    #【备注】紧接着可以进入子模块目录执行 git checkout <指定版本>,如 v1.7.16 或 commit ID
git commit -m "add submodule"     #【提交】父仓库的子模块引用变更(必须及时提交,中途不能做其它操作)
#cat .gitmodules                  #〖查看〗子模块列表      (用于验证是否成功添加)
#cat .git/config                  #〖查看〗父仓库配置及子模块列表(用于验证是否成功添加)

PS:克隆父仓库的同时,同步拉取子模块的方法,例如:
git clone --recurse-submodules https://github.com/your-username/my-project.git
PS:如果克隆父仓库时忘记拉取子模块,或者父仓库切换分支,都可以通过下面命令手动初始化和更新子模块:
git submodule update --init --recursive
PS:采用子模块(submodule)模式能显著提升父仓库与子仓库的独立性(父仓库只记录子模块的来源、版本、本地位置),但存在分支切换时的操作限制:父仓库切换分支后,需手动删除原有子模块,并重新拉取对应分支的子仓库代码。

1
2
3
4
#=======【方式二】整合子仓库〖版本代码〗=======
                                  #【添加】子树【指定分支】到【指定目录】src/cjson/(会自动创建目录)(--prefix= 本地路径,简写"-P ";--squash 压缩成一个提交)
git subtree add --prefix=src/cjson https://github.com/DaveGamble/cJSON.git master --squash  #本命令会自动整合并提交
                                  #【如何】指定子树版本?将 "分支名"(如 master)直接替换为 "标签"(Tag,如 v1.7.18)或 "提交哈希"(SHA,如 a1b2c3d)即可

PS:不建议直接在父仓库中修改子仓库代码,否则易导致版本依赖冲突、代码同步错乱;建议通过子仓库独立维护、提交 PR/MR 的方式迭代,避免依赖关系混乱。

03、关联远程仓库

为实现本地代码与远程代码库的同步协作(包括代码推送、拉取、分支管理等操作),首要步骤需完成本地仓库与目标远程仓库的关联配置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#-------关联远程仓库-------
                                  #【关联】远程仓库(实际是为网址起个别名,即 origin(系统默认别名)代表 https://github.com/espressif/esp-idf.git 这个网址)
git remote add origin https://github.com/espressif/esp-idf.git
#git remote add gitee https://gitee.com/espressif/esp-idf.git  #可以关联多个远程仓库,别名叫 gitee

#-------后续维护:常规操作-------
#git remote -v                    #【查看】所有远程仓库别名与网址
#git remote rm origin             #【移除】远程仓库(移除 origin 对应的网址)
#git remote add origin https://gitee.com/espressif/esp-idf.git 
                                  #【关联】远程仓库(前面先移除,后面新关联,即是实现更改远程仓库关联。当然也可用下面 set-url 更改)
#git git remote set-url origin https://gitee.com/espressif/esp-idf.git 
                                  #【更改】远程仓库(更改 origin 对应的网址)(也可使用 git config -e 直接更改里面的URL)
#git remote add origin git@gitee.com:espressif/esp-idf.git 
                                  #【关联】远程仓库(使用 SSH 协议方式)
04、版本状态查看

执行 Git 关键操作(如分支合并、版本回滚、历史提交修改等)前,建议先通过 git status、git log 等命令核查代码状态与版本上下文,待全面确认无异常后再推进操作,避免因信息缺失引发异常。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#-------查看提交历史-------
git log                           #【查看】提交历史(如果很多信息时,按 f/b 键表示向前/向后翻页, 按 j/k 键表示向前/向后翻行,按 q 键后退出查看)
#git log --oneline                #【查看】提交历史,并且以“一个版本一行”的精简方式显示。
#git log origin/main              #【查看】远程跟踪分支的提交信息
#git log develop..origin/develop  #【查看】远程跟踪分支比当前指定分支多出的提交信息(待合并的变更)
git reflog                        #【查看】操作历史(例如:分支改名、提交代码等), 核心用途分析一些人为误操作。(默认保留 90 天,过期后会被清理)
#git reflog --date=iso            #【查看】操作历史,并且显示时间戳(当紧接在 reflog 后面加 show master 表示查看指定分支 master)
git status                        #【查看】当前分支的【暂存区+工作区】的文件(夹)状态(与本地仓库(HEAD 指针指向的提交)的状态差异比较)
                                  # staged  (已暂存) <- 暂存区的文件状态
                                  # untrack (未跟踪) <- 工作区的文件状态
                                  # modified(已修改) <- 工作区的文件状态
05、版本提交推送

创建工程或修改代码后,日常需执行代码版本保存、提交记录与远程仓库推送操作,形成标准化开发闭环。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#-------当远程仓库为刚新建时-------
git push -u origin main           #【推送】本地仓库到【远程仓库】(-u 选项仅在首次向新创建的远程仓库或新分支推送代码时才添加,-u 是 --set-upstream 简写)
                                  # 如果推送所有分支,则 main 改为 --all 即可。如果还有标签,则 git push -u origin --tags 推送所有标签
#-------当本地进行修改代码时-------
git add .                         #【添加】工作区文件到【暂存区】(. 表示当前目录及其下级所有文件(夹),当然也可以添加指定文件,例如:git add README.md)
git commit "fixed bug"            #【提交】暂存区文件到【本地库】(fixed bug 是提交的文字说明)
git pull origin main              #【拉取+合并】自远程仓库最新代码(合并远程仓库和本地仓库两者的最新代码,为推送到远程仓库准备)
git push origin main              #【推送】到远程仓库(推送 main 分支)

#-------临时缓存用户名和密码-------
git config --global credential.helper cache  #【缓存】用户名和密码(当频繁通过 HTTPS 操作远程仓库,可避免每次重复输入凭证,除非凭证过期或终端关闭)
#git config --global credential.helper 'cache --timeout=1800' #【修改】缓存有效期为 30 分钟(默认缓存 15 分钟)

技术开发过程中难免存在疏漏,即便在执行 Git 等版本控制命令时,也可能因指令输入失误等操作问题,导致需要对已提交的版本进行调整或修复。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#-------当发现提交内容有误时-------
git commit --amend                #〖情形一〗当你刚提交就发现描述内容有误,此时可运行本命令修改描述内容(备注:版本号将重新生成并覆盖原有ID)

git add .                         #〖情形二〗当你刚提交就发现代码内容有误,修改后即可重新添加并提交代码(备注:版本号将重新生成并覆盖原有ID)
git commit --amend --no-edit

sudo gedit .gitignore             #〖情形三〗当你发现一些文件(夹)漏了忽略,则先用文本编辑工具增加忽略规则,再执行下面命令移除追踪并提交新版本记录
git rm --cached *.o               # 从 git 的数据库中删除对于【该类文件】的追踪记录
git rm --cached -r output/        # 从 git 的数据库中删除对于【该文件夹】的追踪记录
git add --all                     # 添加修改(git add --all 表示整个仓库,git add . 表示当前目录及其下级所有文件(夹))
git commit -m "new ignore rule"   # 提交修改

PS:git commit是版本控制标志性的核心操作,作用是将工作区修改固化为本地版本库的正式提交记录。未执行 commit 时(本地修改仅停留在工作区或暂存区,未纳入版本追踪),是导致后续分支合并、代码推送、版本回滚等关键操作失败的主要原因之一!

点击展开内容【Github 的 token 身份验证】

自 2021 年 8 月 13 日起,GitHub 不再支持使用账户密码进行 Git 操作身份验证,转而要求采用基于令牌(token)的验证方式 —— 向 GitHub 提交代码时,输入账号后需填写 token 作为验证凭证。

../img/20190118_009.jpg
../img/20190118_010.jpg

   
06、历史版本回退

当需重新测试旧版本代码或恢复历史配置时,可通过版本回滚(或回退)操作还原旧版本环境;需重点注意:数据无价,所有回退类操作必须谨慎执行,建议提前备份关键数据。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#-------【回滚】到指定的某个版本-------
git revert 7dcbadaaa6ad25c       #【回滚】到指定某个旧版本(其之后的新版本会保留下来),然后在弹出窗口编辑提交注释。(7dcbadaaa6ad25c 是版本id,在确保唯一的前提下输入前面7-8位即可)
#git revert HEAD^^               #【回滚】到当前上上一个旧版本(其之后的新版本会保留下来),然后在弹出窗口编辑提交注释。
#git revert -n HEAD~3            #【回滚】到当前倒数第3个旧版本(其之后的新版本会保留下来),但不自动提交到本地仓库,需要手动提交一次。
                                 # -n 表示不自动提交到本地仓库,需要手动 git commit -m "文字说明" 提交一次。

#-------【回退】到指定的某个版本-------
git reset --hard f69c801587af44f #【回退】到指定某个旧版本(其之后的新版本被永久删除),数据无价操作必须要谨慎!(f69c801587af44f 是版本id,在确保唯一的前提下输入前面7-8位即可)
#git reset --hard                #【回退】到最后旧版本(主要目的是为清除【暂存区】和【工作区】没提交的内容。如果清除不彻底,可接着运行 git clean -dfx 删除未跟踪目录和文件(并含 .gitignore 忽略的内容))
#git reset --hard HEAD^          #【回退】到当前上一个旧版本(其之后的新版本被永久删除)。
#git reset --hard HEAD^^         #【回退】到当前上上一个旧版本(其之后的新版本被永久删除)。
#git reset --hard HEAD~20        #【回退】到当前倒数第20个旧版本(其之后的新版本被永久删除)。
#git reset HEAD                  #【清除】当前【暂存区】add 的内容。
#git reset HEAD -- test.c        #【清除】当前【暂存区】add 的某个文件。
                                 # --soft  修改 HEAD 指针指向,【缓存区】内容【不变】,【工作区】内容【不变】;
                                 # --mixed 修改 HEAD 指针指向,【暂存区】内容【丢失】,【工作区】内容【不变】; <- 默认选项,可不写出来
                                 # --hard  修改 HEAD 指针指向,【暂存区】内容【丢失】,【工作区】内容【恢复】;
#git push -f origin main         #【回退】操作后需要【推送】到远程仓库时,必须加 -f 强制推送,否则会被拒绝(备注:同时托管网站有一个配置开关--是否允许强制推送,例如[gitlab]托管网站解除保护[Setting → Protected Branches → Unprotect])
                                 #【如果】你仅仅是用旧版本代码进行测试,正确做法是先创建并切换到临时分支,再回退到旧版本!

PS:所谓的【回滚】表示将【旧版本】提取出来进行一次【新提交】,即表示【不会】删除任何版本代码!而【回退】则是表示删除节点之后的所有新版本,意味着数据不可恢复,必须谨慎操作!
PS:若仅需基于旧版本代码开展测试,规范操作流程为:先创建并切换到临时分支,再回退至目标旧版本进行验证;严禁直接修改或操作原始代码分支!数据安全至关重要,技术操作需秉持严谨审慎原则,避免因误操作导致不可逆损失。

07、分支操作

在实际开发规范中,main/master 主分支禁止直接提交代码,仅允许通过其他分支(通常为 develop 分支)合并接入。因此,我们会按规范创建各类功能分支,并在对应分支上开展开发工作。以下是分支管理的常规操作(流程):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#-------分支的【查看-改名】操作-------
git branch                       #【查看】所处分支(列表中带"*"表示当前所处分支)
git branch -a                    #【查看】全部分支(包括当前分支和【远程跟踪分支】,例如:隐藏的【远程跟踪分支】 origin/abc,显示为红色的 remotes/origin/abc)
git branch -v                    #【查看】所处分支(较细节信息)
git branch -vv                   #【查看】所处分支(更细节信息)
git branch -m bbbb cccc          #【修改】分支名称(将名称 bbbb 改为 cccc)
git branch -m cccc               #【修改】分支名称(将当前分支改名为 cccc)

#-------分支的【创建-删除】操作-------
git branch aaaa                  #【创建】新的分支(名称为 aaaa)(注:只支持一级分支,但名称可以用"/"字符,例如:release/v5.1)
git branch -d aaaa               #【删除】指定分支(如果 -D 表示强制删除)
git push origin -d aaaa          #【删除】远程分支(注意是【远程分支】)
#git checkout -b bbbb            #【创建并跳到】新的分支(名称为 bbbb)

#-------分支的【切换-合并】操作-------
#git clean -dfx                  #【删除】未跟踪目录和文件(并含 .gitignore 忽略的内容),为彻底切换分支准备。(注意:删除的数据不可恢复,必须谨慎操作!)
git checkout develop             #【切换】到指定仓库(名称为 develop)(因某些操作引起 checkout 也未必完全检出全部代码,此时可以使用 git reset --hard 重置代码)
#git checkout f9f86bdd3aafd      #【切换】到指定版本(git checkout 可以切换到指定【分支】【标签】【版本】)
git merge aaaa                   #【合并】指分支到当前分支(将 aaaa 合并到 develop)(merge 后面可加 --no-ff 和 -m "自定义描述说明",其中 --no-ff 表示禁用 Fast forward)
#git merge --squash aaaa         #【合并】指分支到当前分支,并整合提交信息

#-------分支的【拉取-合并】操作-------
git fetch origin develop         #【获取】远程分支代码和历史
#git log origin/main             #【查看】远程跟踪分支的提交信息
#git log develop..origin/develop #【查看】远程跟踪分支比当前指定分支多出的提交信息(待合并的变更)
#git diff origin/develop         #【比较】远程跟踪分支与当前分支差别(先人工解决冲突,为合并顺利进行准备)(建议使用【小乌龟】可视界面比较)
git merge origin/develop         #【合并】远程跟踪分支到当前分支(origin/develop 合并到 develop)
#git pull origin develop         #【拉取+合并】远程分支到当前分支(git pull 相当于 git fetch + git merge 的默认操作)

PS:手动执行 git fetch + git merge 替代 git pull,核心价值是 “先看后合”—— 通过 git diff 提前了解远程变更,让合并过程更可控,尤其适合多人协作、远程变更频繁的场景。步骤虽多两步,但能有效减少冲突风险和误操作,是更规范的协作实践。
PS:关于使用 git diff 分析版本差异,个人更建议使用【小乌龟】的可视界面来协助分析,提高效率:
../img/20190118_005.jpg

08、标签操作

当发布一个里程碑版本时,我们通常先在版本库中打一个标签,方便后续快速定位和切换到该版本(比分支更适合标记固定版本)。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照(注:checkout标签的源代码只能查看不能修改!)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#-------标签的【查看-改名】操作-------
git ls-remote --tags origin            #【列出】远程所有标签
git tag                                #【列出】当前仓库的所有标签
git tag -n                             #【列出】当前仓库的所有标签及说明
git tag -l v1.0.*                      #【列出】当前仓库的相关标签(支持指定标签、支持通配符*过滤)
git show v1.0.1                        #【查看】指定标签信息(可查到commit的版本id,可用于回退操作)
git checkout v1.0.0                    #【切换】到指定标签的代码(只能用于查看代码),提示当前处于 “detached HEAD" 状态,因 tag 相当于一个快照,是不能更改的!
git checkout -b fix-v1.0.0-bug v1.0.0  #【基于】指定标签创建分支(可用于修复老版本)(基于 v1.0.0 标签创建一个 fix-v1.0.0-bug 分支)

#-------标签的【创建-删除】操作-------
git tag -a v1.0.1 -m "测试版"          #【创建】标签:标签名为"v1.0.1",描述为"测试版"
#git tag v1.0.1                        #【创建】标签:标签名为"v1.0.1"
git tag -a v1.1.0 -m "正式版" 1a2b3c4  #【创建】标签:基于"1a2b3c4"版本创建,标签名为"v1.0.1",描述为"正式版"
#git tag v1.1.0-beta 1a2b3c4           #【创建】标签:基于"1a2b3c4"版本创建,标签名为"v1.0.1"
git tag -d v1.0.0-beta                 #【删除】本地标签(需先删本地,再推送到远程)─┐
git push origin -d v1.0.0-beta         #【删除】远程标签(需先删本地,再推送到远程)←┘

#-------标签的【推送-拉取】操作-------
git push origin v1.0.0                 #【推送】指定标签到远程仓库(推送 v1.0.0 标签到远程仓库)
#git push origin --tags                #【推送】所有本地标签到远程仓库
git fetch origin v1.0.0                #【获取】指定远程标签(从远程仓库获取 v1.0.0 标签)
#git fetch origin --tags               #【获取】远程所有标签(同时拉取分支更新)

PS:标签可理解为一个 “固定不变的游离分支”—— 它本质是指向特定提交节点的静态引用(不随代码提交推进),因此其相关命令操作(如创建、推送、删除等)与分支命令的使用逻辑高度相似。

09、子模块操作
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#-------新增操作:关联子模块〖版本链接〗-------
                                  #【添加】子模块【指定分支】到【指定目录】src/cjson/(会自动创建目录)
git submodule add -b master https://github.com/DaveGamble/cJSON.git src/cjson    #【备注】紧接着可以进入子模块目录执行 git checkout <指定版本>,如 v1.7.16 或 commit ID
git commit -m "add submodule"     #【提交】父仓库的子模块引用变更(必须及时提交,中途不能做其它操作)
#cat .gitmodules                  #〖查看〗子模块列表      (用于验证是否成功添加)
#cat .git/config                  #〖查看〗父仓库配置及子模块列表(用于验证是否成功添加)

#-------后续维护:更新子模块-------
cd src/cjson                      #【进入】子模块目录
git pull origin master            #【拉取】子模块远程最新代码(假设子模块分支是 master)(当然也可以 git checkout <指定版本>,如 v1.7.16 或 commit ID)
cd ../..                          #【回到】父仓库根目录(git submodule update --recursive 更新所有子模块,还包括孙模块等,但实际工程子模块不一定都需要最新版本)
git add .                         #【添加】更新代码(. 表示当前目录及其下级所有文件(夹))
git commit -m "update submodule"  #【提交】父仓库的子模块引用变更(必须及时提交,中途不能做其它操作)
git push origin main              #【推送】到远程父仓库     (必须及时推送,中途不能做其它操作)

#-------后续维护:删除子模块-------
git submodule deinit src/cjson    #【删除】子模块相关配置信息(当然也可以直接删除 .gitmodules 和 .git/config 里面子模块相关内容)
rm -rf src/cjson                  #【删除】【工作区】子模块文件夹(注意:删除后不可恢复)
rm -rf .git/modules/src/cjson     #【删除】【仓库区】子模块文件夹(注意:删除后不可恢复)(此步可选,当不执行时数据仍可留在父仓库中)
git rm --cached src/cjson         #【删除】仓库对于该文件夹的追踪记录
git add .                         #【添加】更新代码(. 表示当前目录及其下级所有文件(夹))
git commit -m "remove submodule"  #【提交】父仓库的子模块引用变更(必须及时提交,中途不能做其它操作)
git push origin main              #【推送】到远程父仓库     (必须及时推送,中途不能做其它操作)

PS:克隆父仓库的同时,同步拉取子模块的方法,例如:
git clone --recurse-submodules https://github.com/your-username/my-project.git
PS:如果克隆父仓库时忘记拉取子模块,或者父仓库切换分支,都可以通过下面命令手动初始化和更新子模块:
git submodule update --init --recursive
PS:采用子模块(submodule)模式能显著提升父仓库与子仓库的独立性(父仓库只记录子模块的来源、版本、本地位置),但存在分支切换时的操作限制:父仓库切换分支后,需手动删除原有子模块,并重新拉取对应分支的子仓库代码。

10、子树操作
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#-------新增操作:整合子树〖版本代码〗-------
                                  #【添加】子树【指定分支】到【指定目录】src/cjson/(会自动创建目录)(--prefix= 本地路径,简写"-P ";--squash 压缩成一个提交)
git subtree add --prefix=src/cjson https://github.com/DaveGamble/cJSON.git master --squash  #本命令会自动整合并提交
                                  #【如何】指定子树版本?将 "分支名"(如 master)直接替换为 "标签"(Tag,如 v1.7.18)或 "提交哈希"(SHA,如 a1b2c3d)即可
#-------后续维护:更新子树-------
git subtree pull --prefix=src/cjson https://github.com/DaveGamble/cJSON.git master --squash        # ←────────────────────────────┐
git push origin main              #【更新】子树到最新版本(如果因一些特别原因无法更新,建议先〖删除子树〗再重新〖添加子树〗即可) ─┘
                                  #【推送】到远程父仓库 (必须及时推送,中途不能做其它操作)
#-------后续维护:查看子树-------
git subtree split --prefix=src/cjson --branch=cjson #【基于】子树创建分支
git checkout cjson                #【切换】到新建分支  (基于子树创建的分支)
git log                           #【查看】此分支提交记录(查看子树的提交记录)
git checkout main                 #【切换】回到主分支
git branch -D cjson               #【删除】刚才新建的分支(查看完后删除即可)(-D 表强制删除)

#-------后续维护:删除子树-------
rm -rf src/cjson                  #【删除】此模块
git add .                         #【添加】更新代码(. 表示当前目录及其下级所有文件(夹))
git commit -m "remove subtree"    #【提交】父仓库的子树引用变更(必须及时提交,中途不能做其它操作)
git push origin main              #【推送】到远程父仓库    (必须及时推送,中途不能做其它操作)

PS:不建议直接在父仓库中修改子仓库代码,否则易导致版本依赖冲突、代码同步错乱;建议通过子仓库独立维护、提交 PR/MR 的方式迭代,避免依赖关系混乱。

11、团队开发协同

多人协作开发时,先按职责分工明确代码文件归属:每人仅负责自身业务相关文件的开发与修改,尽量避免多人同时操作同一文件,否则推送或合并时必定出现冲突,严重时可能导致文件内容损坏!

11.1、集中式协作

核心特点:有一个中央仓库(如 GitHub/GitLab 上的主仓库),所有成员直接向中央仓库提交代码,依赖中央仓库的分支管理。
适用场景:小团队(10 人以内)、项目复杂度低、迭代速度快。

点击展开内容:

一、标准协作流程(以“集中式+分支规范”为例)

无论哪种模式,团队通常会遵循 “分支管理规范” 来保障协作秩序,最常用的是 Git Flow 或简化版的 GitHub Flow

1. 分支规范(Git Flow 为例)
  • 主分支(长期存在)
    • main/master:生产环境代码,仅通过合并其他分支更新,不允许直接提交;
    • develop:开发环境代码,包含最新的开发功能,作为 feature 分支的合并目标。
  • 辅助分支(临时存在)
    • feature/*:新功能分支,从 develop 分支创建,开发完成后合并回 develop
    • bugfix/*:bug 修复分支,从 develop 分支创建,修复后合并回 develop
    • release/*:发布分支,从 develop 分支创建,用于版本发布前的测试和修复,完成后合并到 maindevelop
    • hotfix/*:紧急修复分支,从 main 分支创建,修复生产环境 bug,完成后合并到 maindevelop
2. 完整协作流程(以开发新功能为例)
  1. 创建分支
    develop 分支创建 feature 分支:

    1
    2
    3
    
    git checkout develop  
    git pull origin develop  # 拉取最新开发代码  
    git checkout -b feature/user-login  # 创建并切换到功能分支  
    
  2. 本地开发与提交
    开发过程中定期提交代码,写清晰的提交信息:

    1
    2
    
    git add .  # 暂存修改  
    git commit -m "feat: 实现用户登录功能(账号密码校验)"  # 提交  
    
  3. 定期同步中央仓库
    避免分支落后于 develop 导致冲突,定期拉取 develop 分支的更新:

    1
    2
    3
    4
    
    git checkout develop  
    git pull origin develop  
    git checkout feature/user-login  
    git merge develop  # 合并 develop 的最新代码,解决冲突  
    
  4. 推送分支到中央仓库
    开发完成后,将 feature 分支推送到中央仓库:

    1
    
    git push origin feature/user-login  
    
  5. 发起合并请求(MR/PR)
    在 GitHub/GitLab 上发起 Merge Request(MR)Pull Request(PR),将 feature/user-login 合并到 develop 分支,同时指定团队成员进行代码审查。

  6. 代码审查与合并

    • 审查者检查代码质量、逻辑正确性、是否符合规范;
    • 若有问题,开发者根据反馈修改并提交(修改记录会自动同步到 MR/PR);
    • 审查通过后,由项目负责人合并分支,删除临时的 feature 分支。
  7. 发布与部署
    develop 分支积累足够多的功能后,创建 release 分支进行测试,测试通过后合并到 main 分支,打版本标签(git tag v1.0.0),并部署到生产环境。

二、关键协作工具与实践

1. 代码审查(Code Review)
  • 工具:GitHub/GitLab 的 MR/PR 功能、Gerrit(开源项目常用);
  • 目的:发现代码 bug、优化代码结构、保障团队代码规范一致;
  • 实践
    • 每个 MR/PR 至少 1 名审查者批准后才能合并;
    • 审查重点:逻辑正确性、代码可读性、性能优化、测试覆盖率。
2. 冲突解决
  • 预防冲突
    • 小步提交、频繁同步(定期拉取中央仓库代码);
    • 功能模块化,避免多人同时修改同一文件的同一部分;
  • 解决冲突
    • 本地合并时冲突:git merge 后会提示冲突文件,手动修改冲突部分,然后 git add + git commit
    • MR/PR 冲突:在 GitHub/GitLab 上直接编辑冲突文件,或本地解决后推送。
3. 持续集成/持续部署(CI/CD)
  • 工具:GitHub Actions、GitLab CI、Jenkins;
  • 作用:自动化测试、构建、部署,减少手动操作,保障代码质量;
  • 实践
    • 每个 MR/PR 触发自动化测试(单元测试、集成测试),测试通过才能合并;
    • 合并到 main 分支后,自动构建并部署到测试/生产环境。
4. 提交规范
  • 目的:统一提交信息格式,便于后续追溯和自动化生成版本日志;
  • 规范(以 Conventional Commits 为例)
    • 格式:类型( scope ): 描述,如 feat( login ): 新增验证码登录功能
    • 类型:feat(新功能)、fix(bug 修复)、docs(文档修改)、style(代码格式调整)、refactor(代码重构)等。

三、团队协作注意事项

  1. 避免直接提交主分支:主分支(main/develop)仅通过合并更新,防止误提交导致代码混乱;
  2. 及时沟通:开发前明确任务分工,避免多人同时修改同一功能;遇到问题及时同步,避免冲突积累;
  3. 定期清理分支:合并后的临时分支(feature/bugfix)及时删除,保持仓库整洁;
  4. 备份代码:虽然 Git 是分布式的,但重要分支(如 main/develop)建议定期备份,避免意外丢失;
  5. 新手引导:团队新成员需熟悉分支规范和协作流程,可通过文档或导师指导快速上手。

11.2、多人在多个分支开发

核心特点:每个成员都有完整的本地仓库,中央仓库仅作为 “代码共享中心”,成员间可直接协作(如跨团队贡献)。
适用场景:大团队、开源项目、跨部门协作。

点击展开内容:

Git 分布式协作典型案例:跨团队开源项目协作

以下以 开源项目(如一个智能家居设备控制 SDK) 为例,完整展示 Git 分布式协作的全流程。该场景中,核心团队维护中央仓库,外部贡献者(跨公司/跨地域)通过分布式模式提交代码,无需直接操作中央仓库,兼顾协作灵活性和代码安全性。

一、案例背景

  • 项目:开源智能家居 SDK(仓库地址:https://github.com/smarthome/sdk.git),核心团队(3人)负责维护,支持外部开发者贡献功能/修复 Bug。
  • 角色
    • 核心维护者(A):管理中央仓库,审核 PR,合并代码;
    • 核心开发者(B):参与核心功能开发,协助审查代码;
    • 外部贡献者(C):来自另一家公司,希望为 SDK 新增“蓝牙设备适配”功能。
  • 协作目标:贡献者 C 无需加入核心团队,通过分布式协作将代码合并到中央仓库,同时保证代码质量。

二、完整协作流程(分角色操作)

阶段 1:准备工作(贡献者 C)
1. 复制中央仓库到个人仓库(Fork)

分布式协作的核心是“个人仓库作为中间层”,贡献者先将中央仓库 Fork 到自己的 GitHub 账号下(相当于创建中央仓库的副本):

  • 访问中央仓库地址 https://github.com/smarthome/sdk.git
  • 点击右上角「Fork」按钮,等待复制完成,得到个人仓库:https://github.com/contributor-c/sdk.git
2. 克隆个人仓库到本地

贡献者 C 在本地克隆自己的仓库(而非中央仓库),进行开发:

1
2
3
# 克隆个人仓库到本地
git clone https://github.com/contributor-c/sdk.git
cd sdk
3. 添加中央仓库为上游(Upstream)

为了同步中央仓库的最新代码(避免开发时分支落后),将中央仓库设置为本地仓库的“上游仓库”:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 添加上游仓库(中央仓库),命名为 upstream(自定义名称)
git remote add upstream https://github.com/smarthome/sdk.git

# 验证远程仓库配置(此时有 origin:个人仓库,upstream:中央仓库)
git remote -v
# 输出如下:
# origin    https://github.com/contributor-c/sdk.git (fetch)
# origin    https://github.com/contributor-c/sdk.git (push)
# upstream  https://github.com/smarthome/sdk.git (fetch)
# upstream  https://github.com/smarthome/sdk.git (push)
阶段 2:本地开发(贡献者 C)
1. 同步中央仓库最新代码

开发前先拉取中央仓库 develop 分支(开发分支)的最新代码,避免冲突:

1
2
3
4
5
6
7
8
# 拉取上游仓库(中央)的所有分支信息
git fetch upstream

# 切换到本地 develop 分支(若不存在则创建)
git checkout develop || git checkout -b develop

# 合并上游 develop 分支的最新代码到本地 develop
git merge upstream/develop
2. 创建功能分支开发

遵循分支规范,从 develop 分支创建功能分支:

1
git checkout -b feature/bluetooth-adapter
3. 本地开发与提交

开发“蓝牙设备适配”功能,定期提交代码(提交信息遵循规范):

1
2
3
4
5
6
7
8
# 暂存修改
git add .

# 提交(遵循 Conventional Commits 规范)
git commit -m "feat(bluetooth): 新增蓝牙设备适配功能,支持 BLE 协议"

# 若需多次提交,重复上述步骤
git commit -m "fix(bluetooth): 修复蓝牙连接超时问题"
4. 再次同步中央仓库代码

开发过程中,中央仓库可能有其他贡献者的代码合并,需再次同步避免冲突:

1
2
3
4
5
6
7
8
9
# 拉取上游 develop 最新代码
git fetch upstream

# 合并到当前功能分支
git merge upstream/develop

# 若有冲突,手动修改冲突文件,然后提交
git add .
git commit -m "merge: 解决与上游 develop 分支的冲突"
阶段 3:推送代码到个人仓库(贡献者 C)

开发完成后,将功能分支推送到自己的个人仓库(而非中央仓库):

1
2
# 推送 feature/bluetooth-adapter 分支到个人仓库(origin)
git push origin feature/bluetooth-adapter
阶段 4:发起合并请求(PR)(贡献者 C)

通过 GitHub 界面发起“从个人仓库到中央仓库”的 Pull Request,请求核心团队审核:

  1. 访问个人仓库 https://github.com/contributor-c/sdk.git
  2. 切换到 feature/bluetooth-adapter 分支;
  3. 点击「Compare & pull request」按钮;
  4. 选择目标仓库:smarthome/sdk(中央仓库),目标分支:develop
  5. 填写 PR 描述:功能说明、测试方式、相关文档等;
  6. 点击「Create pull request」提交。
阶段 5:代码审查与修改(核心团队 + 贡献者 C)
1. 核心团队审核(A 和 B)
  • 核心维护者 A 收到 PR 通知,查看代码:逻辑正确性、是否符合 SDK 规范、测试覆盖率;
  • 核心开发者 B 协助审查,提出修改意见(如“补充蓝牙设备断开重连逻辑”“优化日志输出”)。
2. 贡献者 C 响应修改

根据审查意见在本地修改代码,修改后推送到个人仓库,PR 会自动同步更新:

1
2
3
4
5
6
# 本地修改代码后提交
git add .
git commit -m "refactor(bluetooth): 补充断开重连逻辑,优化日志格式"

# 推送修改到个人仓库的功能分支(PR 自动更新)
git push origin feature/bluetooth-adapter
3. 重复审查与修改

直到核心团队确认代码符合要求,审核通过。

阶段 6:合并代码到中央仓库(核心维护者 A)

审核通过后,核心维护者 A 将 PR 合并到中央仓库的 develop 分支:

  1. 在 GitHub PR 页面点击「Merge pull request」;
  2. 选择合并方式(如「Squash and merge」:将所有提交压缩为一个,保持中央仓库历史整洁);
  3. 填写合并信息,点击「Confirm squash and merge」;
  4. 合并完成后,删除中央仓库的临时分支(feature/bluetooth-adapter)。
阶段 7:同步中央仓库最新代码(贡献者 C)

合并完成后,贡献者 C 可将中央仓库的合并结果同步到自己的仓库,便于后续继续贡献:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 拉取上游 develop 分支的最新代码(包含刚合并的自己的功能)
git fetch upstream
git checkout develop
git merge upstream/develop

# 推送同步后的 develop 分支到个人仓库
git push origin develop

# (可选)删除本地功能分支
git branch -d feature/bluetooth-adapter

三、分布式协作的核心优势(案例体现)

  1. 无需核心权限:贡献者 C 无需中央仓库的写权限,通过 Fork + PR 即可贡献代码,保障中央仓库安全;
  2. 本地完整仓库:贡献者 C 本地有完整的仓库,可离线开发、自由提交,仅在需要同步时连接网络;
  3. 跨团队无壁垒:核心团队与外部贡献者无需统一账号、无需线下沟通,通过 PR 流程即可完成协作;
  4. 代码审查可控:所有外部代码必须经过核心团队审核才能合并,保证项目质量。

四、关键注意事项

  1. 定期同步上游代码:避免功能分支落后于中央仓库,减少冲突概率;
  2. 遵循分支与提交规范:统一的分支命名(feature/*)和提交信息规范,便于核心团队审核和追溯;
  3. PR 描述清晰:详细说明功能用途、测试方式,降低审核成本;
  4. 冲突及时沟通:若合并时出现复杂冲突,可在 PR 评论区与核心团队沟通解决。

总结

该案例完整展示了 Git 分布式协作的核心流程:Fork 中央仓库 → 本地开发 → 推送个人仓库 → 发起 PR → 审核修改 → 合并中央仓库。这种模式适合开源项目、跨团队协作场景,既保证了中央仓库的稳定性,又能灵活吸纳外部贡献,是 Git 最具代表性的协作方式之一。


总结

1、操作关系
元素 说明
远程仓库
(Remote Repository)
  • 位于远程服务器上的代码仓库
  • 常见的托管平台:GitHub、GitLab、Gitee
  • 用于团队协作和代码备份
远程分支
(Remote Branch)
  • 远程仓库中的实际分支
  • 团队共享的分支状态
本地仓库
(Local Repository)
  • 位于 .git 目录中的完整版本库
  • 包含完整的提交历史、分支、标签等元数据
  • 通过 git commit 将暂存区内容保存到本地仓库
远程跟踪分支
(Remote Tracking Branch)
  • 本地仓库中远程分支的引用【副本】
  • 命名格式:origin/branch-name
  • 通过 git fetch 更新,但不自动合并
  • 只读(不能直接提交)
本地分支
(Local Branch)
  • 本地仓库中的分支引用
  • 如:maindevelopfeature/login
  • 指向特定提交的指针
暂存区
(Staging Area/Index)
  • 准备提交的更改的中间区域
  • 通过 git add 将工作区的更改添加到暂存区
工作区
(Working Directory)
  • 本地文件系统中实际可见和编辑的文件目录
  • 存在尚未被 Git 跟踪或已修改但未暂存的文件

../img/20190118_006.jpg

2、命令概览

../img/20190118_007.jpg

3、命令选项

一、常用选项表

选项语法 音标 英文释义 中文释义
--all [ɔːl] all 全部,用于推送所有分支、清理所有未跟踪内容
--amend [əˈmend] amend 修改提交,修正最近一次提交的信息或文件
--no-edit no edit 不更改提交信息,合并/变基时跳过编辑步骤
--no-ff no fast forward 禁用快速合并,强制生成合并提交记录
--hard [hɑːd] hard 硬重置,覆盖 HEAD、暂存区、工作区的所有修改
--mixed [mɪkst] mixed 混合重置,默认模式,仅重置 HEAD 和暂存区
--soft [sɒft] soft 软重置,仅移动 HEAD 指针,保留暂存区和工作区
--cached [kæʃt] cached 缓存,针对暂存区操作(如移除已暂存文件不删除本地)
--recursive [rɪˈkɜːsɪv] recursive 递归,克隆时拉取所有嵌套子模块
--recurse [rɪˈkɜːs] recurse 递归,用于子模块相关的递归操作
--global [ˈɡləʊbl] global 全局,配置 Git 全局参数(如用户名、邮箱)
--prefix [ˈpriːfɪks] prefix 前缀,为克隆/操作添加路径前缀
--squash [ˈskwɒʃ] squash 挤塞,整合时压缩成一个提交
-m [ˈmesɪdʒ] message 注释信息,指定提交或标签的说明文本
-n [nəʊ] no 不执行操作,仅预览命令执行效果
-b [brɑːntʃ] branch 分支,创建并切换新分支
-d [dɪˈliːt] delete 删除,删除本地分支或标签
-v [vjuː] view/verbose 查看/详细输出,显示命令执行的详细信息
-f [fɔːs] force 强制操作,强制推送、覆盖标签等
HEAD [hed] head 当前指针,指向当前所在的分支或提交

二、常用单词表

单词语法 音标 英文释义 中文释义
init [ɪˈnɪt] initialization 初始化本地仓库,创建 Git 管理目录
add [æd] add 添加文件到暂存区,标记待提交的修改
rm [rɪˈmuːv] remove 移除文件,删除跟踪或暂存的文件
commit [kəˈmɪt] commit 提交暂存区到本地仓库,生成版本记录
status [ˈsteɪtəs] status 查看工作区/暂存区状态,确认文件变更情况
reset [riːˈset] reset 重置版本指针,回退到指定历史版本
revert [rɪˈvɜːt] revert 回滚指定提交,生成反向提交抵消变更
branch [brɑːntʃ] branch 分支管理,创建、查看、删除分支
checkout [ˈtʃekaʊt] checkout 检出分支/恢复文件,切换分支或还原文件
merge [mɜːdʒ] merge 合并分支,将目标分支代码合并到当前分支
tag [tæɡ] tag 标记版本标签,为重要提交打版本快照
remote [rɪˈməʊt] remote 远程仓库管理,添加、查看、修改远程地址
push [pʊʃ] push 推送本地内容到远程,同步本地提交到服务器
pull [pʊl] pull 拉取并合并远程更新,等价于 fetch+merge
fetch [fetʃ] fetch 拉取远程更新,仅同步远程跟踪分支不合并
clone [kləʊn] clone 克隆远程仓库到本地,下载完整代码和历史
ignore [ɪɡˈnɔː(r)] ignore 忽略指定文件,配置不被 Git 跟踪的文件
submodule [ˌsʌbˈmɒdjuːl] submodule 子模块管理,嵌套管理其他 Git 仓库
foreach [fəˈriːtʃ] foreach 遍历执行命令,对所有分支/子模块批量操作
origin [ˈɒrɪdʒɪn] origin 默认远程仓库别名,指代克隆的源仓库地址