# 代码管理相关知识点 ## Git ### Git的概念 Git是一个开源的分布式版本控制系统,它能够高效地处理从小到大的项目。 #### 三个区域的概念 - 工作区 平时存放项目的地方,可以在工作区直接修改。 - 暂存区 用于临时存放改动,保存即将提交的文件列表信息。 - 仓库区(版本库) 就是安全存放数据的位置,这里面有提交到所有版本的数据(版本快照)。 - 仓库的概念 - Git仓库是存储文件和历史记录的地方。 - 节点的概念 是Git中的基本概念,它代表着代码库的一个特定状态。每当你在Git中提交代码时,都会创建一个新的节点来保存当前代码库的状态。每个节点都有一个唯一的标识符,即SHA-1哈希值,用来标识该节点的内容和父节点。 - 分支的概念 是基于节点的一个引用,它指向一个节点作为该分支的起点。通过创建分支,可以在代码库中开发新的功能、修复bug或实施其他更改,而不会影响原始分支。每个分支都有一个名称,通常用来描述该分支的目的或特点。分支之间可以相互合并,通过合并可以将不同分支上的更改合并到一起。 - 文件的状态 - 已修改:文件内容已经被修改。 - 已删除:文件本身已经被删除(工作区删除,存储区还有)。 - 变 更:文件本身没有修改,但是改变了存放位置。 - 未管理:尚未添加到版本管理的文件,比如新添加的文件。 - 忽 略:不需要添加到版本管理的文件。 - 冲 突:合并的时候同时修改了同一块的内容,所有需要人为取解决冲突。 ## SourceTree ### SourceTree的概念 - SourceTree 是 Windows 和Mac OS X 下免费的 **Git 客户端,**拥有可视化界面,容易上手操作。 ### 仓库相关操作 #### **创建本地仓库**(修改) 1. 有文件夹创建新文件 ***在浏览里面选择我们要创建本地仓库的文件夹。*** ![image-20250708170825330](./pictures/image-20250708170825330.png) ![image-20250716161207295](./pictures/image-20250716161207295.png) 点击是 ![image-20250716161240555](./pictures/image-20250716161240555.png) 创建成功 ![image-20250716161315531](./pictures/image-20250716161315531.png) 浏览里面选择要创建仓库的文件夹,即可以在该文件夹建立一个仓库,生成.git文件。 2. 没有文件夹创建本地仓库 - 选择路径 ![image-20250716162208546](./pictures/image-20250716162208546.png) - 桌面出现文件夹 ![image-20250716162311987](./pictures/image-20250716162311987.png) - 仓库建立成功 ![image-20250716162354532](./pictures/image-20250716162354532.png) #### **打开本地仓库** ![image-20250708170902654](./pictures/image-20250708170902654.png) **注意:在打开目标仓库的路径时候,不能点进隐藏文件.git文件** ![image-20250715083550523](./pictures/image-20250715083550523.png) #### **克隆远程仓库**(修改) **获取URL:http://gitea.xinje.cc/wangshunkui/kong.git** ![image-20250715083923012](./pictures/image-20250715083923012.png) **克隆** - 填写URL地址和Clone到的空文件夹 ![image-20250708171125862](./pictures/image-20250708171125862.png) - 远端的内容 ![image-20250716162610646](./pictures/image-20250716162610646.png) ![image-20250716162825962](./pictures/image-20250716162825962.png) - 点击克隆 ![image-20250716162936996](./pictures/image-20250716162936996.png) - 实现结果 ![image-20250716163014791](./pictures/image-20250716163014791.png) #### **获取** **获取是从远程仓库获取信息并同步至本地仓库(获取只会同步到本地仓库,不会更改工作文件)** ![image-20250709090736034](./pictures/image-20250709090736034.png) #### **关联远程仓库** ![image-20250715084429589](./pictures/image-20250715084429589.png) ![image-20250715084510609](./pictures/image-20250715084510609.png) ![image-20250715084704021](./pictures/image-20250715084704021.png) 注意:步骤四自己对远端电脑随便取个名就行。 ​ 在 `SourceTree` 中,**克隆远程仓库**是指从远程 Git 仓库中下载完整的项目代码和提交历史,创建一个新的本地项目副本;而**关联远程仓库**是指在本地已存在的 Git 仓库中,添加一个远程仓库地址,以便将本地代码推送到远程或从远程拉取更新。两者的主要区别在于:克隆用于从远程获取项目,自动建立关联并初始化本地项目;而关联远程用于让已有的本地项目与远程仓库建立联系,通常用于首次推送代码。 ### **节点相关操作** #### **提交** 将工作区的内容放到仓库的这个过程叫做提交。将写完后的文档先添加到暂存区,然后再写日志提交。每一次提交产生一个节点。![image-20250708175643517](./pictures/image-20250708175643517.png)![image-20250708181530873](./pictures/image-20250708181530873.png) #### 回滚提交(修改) “回滚提交”指的是对 Git 历史中的某个提交进行撤销、修改或恢复的操作。常见的回滚行为包括: - **撤销最近的提交** - **恢复到某个旧的提交版本** - **撤销某一次错误的提交(保留历史)** - 回滚前 ![image-20250716164205932](./pictures/image-20250716164205932.png) ![image-20250716163940888](./pictures/image-20250716163940888.png) ![image-20250716164007116](./pictures/image-20250716164007116.png) - 回滚后 ![image-20250716164356055](./pictures/image-20250716164356055.png) ![image-20250716164339076](./pictures/image-20250716164339076.png) - 回滚的回滚 ![image-20250716164601226](./pictures/image-20250716164601226.png) ![image-20250716164542292](./pictures/image-20250716164542292.png) - 回滚到第一次回滚的回滚 ![image-20250716164703990](./pictures/image-20250716164703990.png) ![image-20250716164730426](./pictures/image-20250716164730426.png) - 回滚多部操作 ![image-20250716164948009](./pictures/image-20250716164948009.png) ![image-20250716165008026](./pictures/image-20250716165008026.png) 产生冲突,需要去解决冲突 #### **重置当前分支到此次提交** ![image-20250715085302303](./pictures/image-20250715085302303.png) ![image-20250715085358478](./pictures/image-20250715085358478.png) - #### Source Tree三种合并和区别(修改) 混合合并: ![image-20250716165347055](./pictures/image-20250716165347055.png) ![image-20250716165412325](./pictures/image-20250716165412325.png) 混合合并以后文件文件保存到了未暂存区,提供一次修改机会。 强行合并: ![image-20250716165606528](./pictures/image-20250716165606528.png) ![image-20250716165635842](./pictures/image-20250716165635842.png) ![image-20250716165650392](./pictures/image-20250716165650392.png) 是指将此次提交回滚到指定的位置,但这个过程中将直接丢弃之前修改的所有文件。 软合并: ![image-20250716165155337](./pictures/image-20250716165155337.png) ![image-20250716165220392](./pictures/image-20250716165220392.png) 软合并之后,文件保存到暂存区,给一次修改机会。 ### **分支相关操作** #### **新建分支** 创建的分支和主分支是完全一样的东西,新建分支旁边有圈代表分支激活,东西保存在该分支当中。 ![image-20250708182630161](./pictures/image-20250708182630161.png) #### **合并分支**(修改) 激活master,选择要合并的支线,点击确定,将支线的所有变化的节点打包创建一个新节点合并过去。 1. 切换到**目标分支**(如 `master`) 2. 点击上方菜单栏的:**分支 → 合并(Merge)** 3. 在弹窗中选择你要合并进来的源分支(如 `dev1`) 4. 点击“确定”开始合并 5. 如果有冲突,会提示你处理冲突 6. 处理完冲突后,**提交合并记录** ##### 分支合并到主分支 ![image-20250715085914861](./pictures/image-20250715085914861.png) ![image-20250715090114147](./pictures/image-20250715090114147.png) ![image-20250715090300179](./pictures/image-20250715090300179.png) ##### 分支1合并到分支2 ![image-20250716174627685](./pictures/image-20250716174627685.png) ![image-20250716174710474](./pictures/image-20250716174710474.png) 解决冲突 ![image-20250716174746235](./pictures/image-20250716174746235.png) 合并成功 ![image-20250716174814521](./pictures/image-20250716174814521.png) ##### 分支的分支合并到主分支 ![image-20250716175432378](./pictures/image-20250716175432378.png) ![image-20250716175501064](./pictures/image-20250716175501064.png) 合并成功 ![image-20250716175527294](./pictures/image-20250716175527294.png) #### **删除分支**(修改) 1. **切换出要删除的分支,你不能删除当前正在使用的分支。请先切换到其他分支**。 2. 在左侧分支列表中,**右键你要删除的分支** 3. 选择 **“删除分支”** 或 4. 会弹出确认窗口,点击 **“删除”** 确认即可 **注意尚未合并的分支不能删除(即没有备份的分支)** ![image-20250716174143186](./pictures/image-20250716174143186.png) ![image-20250716174201453](./pictures/image-20250716174201453.png) ![image-20250716174218591](./pictures/image-20250716174218591.png) 强行删除没有合并的分支 ![image-20250716173351121](./pictures/image-20250716173351121.png) ![image-20250716173413156](./pictures/image-20250716173413156.png) ![image-20250716173444722](./pictures/image-20250716173444722.png) ![image-20250716173340425](./pictures/image-20250716173340425.png) 因为分支没有和主分支合并,所以删除失败 ![image-20250716173539786](./pictures/image-20250716173539786.png) ![image-20250716173551578](./pictures/image-20250716173551578.png) ![image-20250716173721782](./pictures/image-20250716173721782.png) ## 适用场景和意义 | 场景 | 意义 | | -------------------------- | ------------------------------------------------------------ | | 🔁 **分支内容无用** | 某个分支用于试验、测试,最终未采用,强行删除避免冗余。 | | 🧹 **清理历史** | 清理长期未合并、开发中断的“僵尸分支”。 | | 🚫 **修复误操作** | 某分支是误建的,未提交或提交错误,无法 merge,不如直接强制删除。 | | 🔒 **防止危险代码流入主干** | 某分支包含危险改动或潜在 Bug,为避免 merge 到主分支,立即删除。 | | ⚠️ **冲突太多,放弃合并** | 分支与主干差异大、冲突重,重建更清晰,强行删除原分支。 | #### **切换分支**(修改) 双击要切换的分支名字,出现小圆圈为激活状态。 ![image-20250716170731012](./pictures/image-20250716170731012.png) **检出分支** ![image-20250715110124406](./pictures/image-20250715110124406.png) **“检出(checkout)远程分支”** 是指你将某个远程仓库(如 origin)上的分支拿到本地来使用、开发或查看的操作。 #### **制造冲突**(修改) **本地冲突**: 分支2修改: ![image-20250716170409161](./pictures/image-20250716170409161.png) 分支1修改: ![image-20250716170518530](./pictures/image-20250716170518530.png) 合并分支: ![image-20250716170613121](./pictures/image-20250716170613121.png) 产生冲突: ![image-20250716170634869](./pictures/image-20250716170634869.png) 如果分支一修改了`1.txt`,分支2修改了`1.txt`且修改位置意义,修改内容不同合并时候就会产生冲突。 远程冲突: ​ ![image-20250715101748612](./pictures/image-20250715101748612.png) 本地`3.txt`的内容: ![image-20250715101840211](./pictures/image-20250715101840211.png) 远端`3.txt`的内容: ![image-20250715101921523](./pictures/image-20250715101921523.png) 修改本地3.txt的内容: ![image-20250715101958607](./pictures/image-20250715101958607.png) 提交推送: ![image-20250715102053788](./pictures/image-20250715102053788.png) 报错: ![image-20250715102118699](./pictures/image-20250715102118699.png) ![image-20250715102233715](./pictures/image-20250715102233715.png) #### **解决冲突** 本地冲突: ​ 方式一:在需要提交的文件里面自己手动保留要更改的内容,然后鼠标右键选择已经解决冲突。 ​ 方式二:方式是以我为准激活的分支的内容是我要保留的内容。 ​ 方式三:以别人为准就是合并时候保存要合并的那个分支的内容。 远程冲突: ​ 拉取:![image-20250715102301151](./pictures/image-20250715102301151.png) ![image-20250715102318702](./pictures/image-20250715102318702.png) ![image-20250715102348307](./pictures/image-20250715102348307.png) 解决冲突再重新推送: ![image-20250715102453244](./pictures/image-20250715102453244.png) ### **拉取** 选择从远端仓库中哪个分支获取。 ![image-20250715091303896](./pictures/image-20250715091303896.png) ![image-20250708193822773](./pictures/image-20250708193822773.png) ### **推送** 选择要发送到远端仓库的分支,点击推送。 ![image-20250715091337901](./pictures/image-20250715091337901.png) ![image-20250708193624574](./pictures/image-20250708193624574.png) ### 其他 #### 书写忽略文件 方式一:选择修改的文件,右击选择忽略。 ![image-20250708191109627](./pictures/image-20250708191109627.png) 方式二: ![image-20250715091619608](./pictures/image-20250715091619608.png) ![image-20250715091647725](./pictures/image-20250715091647725.png) ![image-20250715091712480](./pictures/image-20250715091712480.png) ![image-20250715091748023](./pictures/image-20250715091748023.png) 1. **忽略指定文件**:在 `.gitignore` 中添加精确文件名,如 `lalala.txt`,表示忽略该文件的所有更改。 2. **忽略特定类型的文件**:使用通配符后缀,如 `*.md` 表示忽略所有 `.md` 结尾的文件。 3. **忽略特定文件夹**:使用路径方式,如 `/name` 表示忽略项目根目录下的 `name` 文件夹及其所有内容。 #### 停止跟踪 停止跟踪的作用是让 Git 不再对某个已经被版本控制的文件或文件夹进行管理,这意味着即使你之后对该文件进行了修改、重命名或删除,Git 也不会再将这些更改记录到提交中。 本地文件停止跟踪: 方式一:选择要停止跟踪的文件,然后右击鼠标,选择停止跟踪。 ![image-20250708194308960](./pictures/image-20250708194308960.png) 方式二:没有更改需要停止跟踪的文件,选择停止跟踪。 1. 第一步,选择要停止跟踪的文件 2. 点击操作 3. 点击停止跟踪 ![image-20250715092825607](./pictures/image-20250715092825607.png) ![image-20250715092854248](./pictures/image-20250715092854248.png) 停止跟踪远程分支: ![image-20250715093055328](./pictures/image-20250715093055328.png) #### 创建补丁(修改) 1. 在 `SourceTree` 中,**选择你要导出补丁的提交 2. 右键点击 → 选择 **“创建补丁”** 或 “Export patch” 3. 选择保存路径,`SourceTree` 会导出为 `.patch` 文件 4. 将该补丁文件发送给他人或用于其他仓库应用 ![image-20250715104051326](./pictures/image-20250715104051326.png) ![image-20250715104131125](./pictures/image-20250715104131125.png) 在分支创建补丁的意义 | 目的 | 原因和优势 | | :-------------------: | :----------------------------------------------------------: | | **1. 避免污染主分支** | 主分支(如 `master`、`main`)通常要保持稳定、可发布。在新建分支上做补丁开发,不会影响主线。 | | **2. 更容易管理改动** | 分支相当于“一个封闭的变更沙箱”,方便组织、测试和提交改动。 | | **3. 方便团队协作** | 提交到分支后,其他开发者可以基于该分支拉取代码、做代码审查(Review)或测试。 | | **4. 创建补丁文件** | 使用 `git format-patch` 可以导出成 `.patch` 文件供邮件发送、打包发布或代码审计。 | #### 应用补丁 选择补丁的位置选择补丁,点击应用。 ![image-20250708201320222](./pictures/image-20250708201320222.png) **1. 分支上的 `1.txt` 内容与补丁内容完全一致** - **表现**:补丁内容已经存在于文件中,Git 会检测到没有变化,通常补丁应用无效或跳过这部分,不会重复添加。 - **结果**:补丁不产生新改动,应用成功但无实际更改。 ![image-20250715104246489](./pictures/image-20250715104246489.png) **2. 分支上的 `1.txt` 是空文件** - **表现**:补丁中添加的内容(`+1`)会被完整地添加到空文件中。 - **结果**:文件由空变成包含补丁内容,补丁完全应用成功。 ![image-20250715104334193](./pictures/image-20250715104334193.png) ![image-20250715104441837](./pictures/image-20250715104441837.png) **3. 分支上的 `1.txt` 内容与补丁内容部分一致** - **表现**:补丁中新增的内容与已有部分有重叠,Git 会尝试合并,可能成功应用新增部分,或者产生冲突需要手动解决。 - **结果**:补丁部分应用成功,冲突部分需人工介入。 ![image-20250715105229020](./pictures/image-20250715105229020.png) ![image-20250715105307319](./pictures/image-20250715105307319.png) ![image-20250715105716186](./pictures/image-20250715105716186.png) ![image-20250715105823879](./pictures/image-20250715105823879.png) ![image-20250715105843945](./pictures/image-20250715105843945.png) ![image-20250715105911056](./pictures/image-20250715105911056.png) **4. 分支中没有 `1.txt` 文件** - **表现**:如果补丁涉及新增文件,Git 会直接创建 `1.txt` 并写入补丁内容;如果补丁只修改文件而文件不存在,则应用失败报错。 - **结果**: - 补丁新增文件时,文件被创建且内容写入。 - 补丁修改文件但文件缺失时,补丁应用失败。 ![image-20250715104610912](./pictures/image-20250715104610912.png)![image-20250715104949285](./pictures/image-20250715104949285.png) ![image-20250715104822311](./pictures/image-20250715104822311.png) ![image-20250715105052163](./pictures/image-20250715105052163.png) #### 贮藏 **贮藏的典型用途:** - 临时切换分支处理紧急任务 - 拉取或合并最新代码前清理工作区 - 保存不完整的改动,避免提交不完整代码 ![image-20250708200138749](./pictures/image-20250708200138749.png)贮藏操作会将你当前工作区和暂存区的改动(包括新增、修改、删除的文件)保存到一个栈中,同时将工作目录恢复到干净状态,就像没有修改过一样。这使你能够 **快速切换分支、拉取最新代码或进行其他操作,而不必担心未完成的改动被提交或丢失**。 #### 丢弃 **丢弃** 指的是放弃当前工作目录或暂存区中的修改,将文件恢复到最后一次提交的状态。也就是说,丢弃操作会撤销你对文件所做的所有未提交更改,使文件内容回到仓库中最新提交的版本。 ![image-20250708195933808](./pictures/image-20250708195933808.png) #### 移除 (直接删除工作区的文件) ![image-20250708195200903](./pictures/image-20250708195200903.png) #### 创建标签(修改) **标识版本**:标签常用来标记软件的版本号,如 `v1.0.0`、`v2.1.3`,方便团队成员和用户明确某次发布对应的代码状态。 **便于回溯**:通过标签可以快速跳转到对应提交,便于查阅、回滚或打包特定版本代码。 **不可变标记**:与分支不同,标签是固定的引用,不会随后续提交移动,保证历史版本的稳定性。 **支持轻量标签和附注标签**:轻量标签只是简单指向提交的指针,附注标签则包含作者信息、日期和描述,适合用于发布说明。 ![image-20250715094336938](./pictures/image-20250715094336938.png) ![image-20250708194852689](./pictures/image-20250708194852689.png) 单击标签,切换到标签的节点所在位置。双击标签可以切换到标签节点的内容。 ![image-20250716165912588](./pictures/image-20250716165912588.png) 双击标签可以切换到标签节点的内容。 ![image-20250716165954714](./pictures/image-20250716165954714.png) ![image-20250716170026082](./pictures/image-20250716170026082.png) #### 删除标签 ![image-20250715094614190](./pictures/image-20250715094614190.png) ![image-20250715110143327](./pictures/image-20250715110143327.png)