一文吃透Git:本地操作|冲突处理|远程协作|GitFlow工作流详解
2026/9/12 20:32:03 网站建设 项目流程

文章说明:本文基于比特就业课Git讲义整理,涵盖Git安装、核心概念、本地操作、分支管理、冲突处理、远程仓库、多人协作、企业GitFlow分支模型,适合入门学习、期末复习、面试复习。


一、什么是版本控制器

1.1 痛点

日常写文档、写代码,为了防止改错丢失,手动复制多份文件:报告‑v1、报告‑v2、报告‑最终版、报告‑究极版。
问题:版本多,记不清每个版本改了什么,多人协同修改文件很难合并。

1.2 版本控制器

记录工程每一次改动、版本迭代,支持版本回溯,方便多人协同作业。Git是目前行业最主流分布式版本控制器。

重要特性:

1. Git主要跟踪文本文件(代码、txt、html),可以精确看到哪一行增删改。

2. 二进制文件(图片、视频、压缩包)仅能保存完整文件,无法看到内部改动细节,只能感知文件大小变化。

二、Git安装与基础配置

2.1 各平台安装命令

1. CentOS7

sudo yum -y install git git --version #查看版本

2. Ubuntu

sudo apt-get install git -y git --version

3. Windows:下载安装包图形化安装。

2.2 用户信息配置(必做!提交代码身份标识)

--global:全局配置,本机所有git仓库生效;不加则仅当前仓库生效。

# 设置用户名和邮箱 git config --global user.name "你的名字" git config --global user.email "你的邮箱" # 查看全部配置 git config -l # 删除配置 git config --global --unset user.name git config --global --unset user.email

三、创建本地仓库 & .git目录详解

3.1 创建本地仓库

仓库就是被Git管理的文件夹。

git init # 在当前目录初始化git仓库

执行后生成隐藏目录 .git,绝对不要手动修改里面文件,会直接损坏仓库。

3.2 .git目录核心文件/文件夹解析

文件/目录作用
index暂存区(stage/index),git add的内容存这里
HEAD指针,记录当前所处分支;内容示例ref: refs/heads/master
refs/heads/存放各个分支,每个文件保存该分支最新commit‑id
refs/tags/存放标签tag信息
objects/对象库,存放git全部提交对象(blob、tree、commit)
hooks/钩子脚本,可在提交/推送前后执行自定义脚本

查看对象内容命令:git cat-file -p commit‑id,可以解析commit对象、tree对象、blob对象。
commit‑id是SHA‑1哈希生成的40位十六进制字符串,不是简单1、2、3自增数字。

四、三大核心区域:工作区、暂存区、版本库

1. 工作区:电脑实际操作的文件夹,我们写代码的地方。

2. 暂存区(stage/index):.git/index,临时存放待提交修改,桥梁。git add将工作区改动放到暂存区。

3. 版本库(repository):.git目录,真正保存历史所有版本;git commit把暂存区数据存入版本库。

关键流程:
工作区 →git add→ 暂存区 →git commit→版本库。
仅仅新建文件,只是工作区文件,git不会管理,必须add+commit。

五、本地基础命令

5.1 添加文件到暂存区 git add

git add 文件名1 文件名2 # 添加指定文件 git add 目录名 # 添加整个目录包括子目录 git add . # 添加当前目录所有改动

5.2 提交到本地版本库 git commit

‑m必须写,填写本次提交说明,方便后续回溯。

git commit -m "提交说明" # 提交暂存区全部内容 git commit 文件1 文件2 -m "xxx" # 只提交暂存区指定文件

5.3 查看提交日志 git log

git log # 完整日志 git log --pretty=oneline # 简洁一行展示,显示commit id+说明 git log --graph --pretty=oneline --abbrev-commit #图形化看分支合并

5.4 查看状态与差异

git status # 查看工作区、暂存区状态,提示下一步操作 git diff # 工作区 vs 暂存区差异 git diff HEAD -- 文件名 # 工作区 vs 版本库最新版本差异

六、版本回退 reset 命令

6.1 reset三种模式

git reset [--soft | --mixed | --hard] [版本标识]
参数版本库暂存区工作区使用风险
--soft回退不变不变安全,只移动HEAD指针
--mixed(默认)回退回退不变常用
--hard回退回退回退⚠️危险,未提交代码直接丢失!

6.2 版本定位写法

HEAD 当前版本 HEAD^ 上一个版本 HEAD^^ 上上版本 HEAD~n 往上n个版本 完整/部分commit‑id 指定某个历史版本

6.3 找回丢失commit:git reflog

git log看不到已经被回退覆盖的commit;git reflog记录本地每一次操作,可以找回所有曾经的commit id。

git reflog git reset --hard 部分commit-id # 恢复到丢失版本

七、撤销修改的三种场景

场景1:修改完,还没有git add(只在工作区)

丢弃工作区修改,恢复到暂存区/版本库状态

git restore 文件名 # 旧写法:git checkout -- 文件名 (--不能省略!)

场景2:已经git add到暂存区,没有commit

第一步:把文件从暂存区撤回到工作区;第二步丢弃工作区修改

git reset HEAD 文件名 # 取消暂存,mixed模式 git restore 文件名 # 丢弃工作区改动

场景3:已经git commit提交本地,还没有push远程

直接版本回退

git reset --hard HEAD^

⚠️注意:如果已经推送到远程仓库,不建议本地reset回退,会造成远程本地版本冲突。

八、删除文件

1. 手动rm删除只是工作区删除,git依然记录该文件。

2. git rm同时删除工作区+暂存区,之后需要commit提交这次删除操作。

git rm 文件名 git commit -m "删除xxx文件"

误删恢复:git restore 文件名

九、Git分支管理

概念:每次commit连成一条时间线就是分支。HEAD不是指向提交,HEAD指向当前分支指针。

master是git初始化默认主分支。

9.1 分支基础命令

git branch # 查看本地所有分支,*代表当前分支 git branch dev # 创建dev分支 git checkout dev # 切换到dev分支 git checkout -b dev # 创建并且直接切换dev(最常用) git merge dev # 将dev分支合并到【当前所在分支】 git branch -d dev # 删除已经合并过的分支 git branch -D dev # 强制删除没有合并完成的废弃分支

注意:不能删除自己当前正在checkout的分支,要切到别的分支再删。

9.2 Fast‑forward快进合并

如果master没有新提交,dev分支直接移动master指针,无新增commit。

缺点:删除分支之后,历史看不出曾经做过合并。

9.3 --no‑ff 禁用快进(推荐正式项目)

合并的时候强制生成一个新merge提交,完整保留分支历史痕迹。

git merge --no-ff -m "合并dev分支" dev

十、合并冲突处理

当两个分支对同一个文件同一处都做了修改,git无法自动合并,出现冲突CONFLICT(content)。

1. git提示冲突,文件内标记冲突标记

<<<<<<< HEAD // 当前分支内容 当前分支代码 ======= //分割线 被合并分支代码 >>>>>>> dev1 //被合并分支名

2. 手动打开文件,删掉<<<<<< ===== >>>>>>标记,编辑成最终想要的代码

3. git add .标记冲突解决

4. git commit -m "解决冲突合并分支"提交,完成合并。

放弃本次合并:git merge --abort

十一、stash 工作现场储藏

场景:正在分支写一半代码,功能没写完,突然需要切别的分支修复bug,不想提交半成品代码。

git stash # 保存当前工作现场,工作区变干净 git stash list # 查看所有储藏的现场 git stash pop # 恢复现场,同时删掉这条stash记录(最常用) git stash apply # 恢复,不删除stash记录,需要手动git stash drop git stash apply stash@{0} # 指定恢复某一条储藏

最佳实践:修复bug,优先在自己本地分支解决冲突,再合并到主分支,不要直接在master解决冲突,保护主分支稳定。

即:dev分支先merge master,冲突在dev解决测试完毕;master再merge dev,此时无冲突。

git stash 通俗讲解

场景:你正在自己分支写代码,代码只写一半,不能提交commit,但是现在要切到别的分支改Bug。
直接切换分支:未保存的代码会跟着跑到另一个分支,代码全部乱掉。
👉stash就是临时把写一半的代码“打包封存起来”,把工作区变回干净状态,等处理完Bug切回来,再把代码恢复出来。

每条命令详解

git stash # 保存当前工作现场,工作区变干净

把工作区、暂存区改动打包存起来。执行完git status,工作目录干干净净,就像没写过这些代码一样。

⚠️只保存已经修改的文件;新创建还没有git add的全新文件,默认不会被stash保存。

git stash list # 查看所有储藏的现场

你可以多次执行git stash,会存多条备份。

输出示例:

stash@{0}: WIP on dev: a23bc4d 完成登录模块 stash@{1}: WIP on dev: 87fa321 开始写聊天框

stash@{0}代表最新保存的那一份现场,数字越大保存时间越早。

git stash pop # 恢复现场,同时删掉这条stash记录(✅最常用)

取出**最新stash@{0}**的代码恢复到工作区;恢复成功之后,这条储藏记录直接删除。

日常90%场景用pop,用完即销毁,不会堆积无用stash。

git stash apply # 恢复,不删除stash记录,需要手动git stash drop

把代码恢复出来,但是备份记录仍然保留在仓库中。

如果后续不需要这条备份,必须手动执行:

git stash drop stash@{0} # 删除指定一条储藏 git stash clear # ⚠️清空全部stash备份
git stash apply stash@{0} # 指定恢复某一条储藏

当你有多份stash备份,不想取最新的,指定恢复某一条。

例:git stash apply stash@{1}恢复更早的那一份代码现场。

📌完整实战流程

1. 在dev分支,写了一半代码,还不能commit

2. git stash # 封存半成品,工作目录干净

3. git checkout master # 切换主分支,去修复线上bug

4. 修改Bug → git commit提交bug修复

5. git checkout dev # 切回自己开发分支

6. git stash pop # 将之前写一半的代码恢复回来,继续开发

⚠️容易踩坑

1. 如果恢复代码的时候,当前文件已经改动,会产生stash冲突,和分支合并冲突一模一样,手动解决标记符号。

2. stash是本地仓库功能,不会上传远程Gitee/GitHub,换电脑就看不到这些储藏。

3. 全新未add的文件不会被stash保存,新文件先执行git add,再stash。

💡一句话面试回答

git stash用于保存尚未提交的工作现场。开发进行到一半需要临时切换分支处理bug,使用stash把半成品临时储藏,处理完别的工作之后再恢复代码。

pop:恢复并删除备份;

apply:恢复但保留备份;

list:查看所有储藏列表。

十二、.gitignore忽略文件

作用:告诉git,某些文件/文件夹不要纳入版本管理,比如编译产物、日志、配置、临时文件。

.gitignore示例内容

*.so *.ini build/ # 排除所有.开头隐藏文件,但保留.gitignore .* !.gitignore

强制添加被忽略的文件:git add -f 文件名

排查哪个规则忽略文件:git check‑ignore -v 文件名

十三、远程仓库(Gitee/GitHub)

Git是分布式版本控制系统:每个人电脑都拥有完整仓库副本,不需要联网也可以本地提交。公共服务器(gitee/github)仅仅方便大家交换代码。

13.1 两种协议

1. HTTPS协议:直接克隆,每次push需要输入账号密码。

2. SSH协议:配置SSH公钥,免密码推送。

SSH密钥配置步骤

1. 生成密钥对:

ssh-keygen -t rsa -C "你的注册邮箱" # 一路回车,生成 ~/.ssh/id_rsa(私钥,保密) id_rsa.pub(公钥,粘贴到gitee)

2. 复制id_rsa.pub全部内容,粘贴到gitee账号‑SSH公钥设置。

13.2 远程仓库基础命令

git clone 远程仓库地址 # 克隆远程仓库到本地,自动生成origin远程别名 git remote # 查看远程仓库别名,默认origin git remote -v # 查看远程仓库详细fetch/push地址 #推送:git push 远程别名 本地分支:远程分支 git push origin master # 本地master推送到远程origin的master git pull origin master # 拉取远程master,并且合并到当前本地分支

推送失败常见原因:远程有别人新提交,本地版本落后,先执行git pull拉取合并,解决冲突,再push。

13.3 本地分支关联远程分支

# 本地新建dev分支,关联origin/dev远程分支 git checkout -b dev origin/dev # 设置已有本地分支追踪远程分支 git branch --set-upstream-to=origin/dev dev

查看全部本地+远程分支

git branch -a git branch -r #只看远程分支

远程已经删除,本地还显示过期远程分支清理:

git remote prune origin

十四、tag标签管理

tag给某一个commit打版本标记,用于版本发布,如v1.0、v2.0。

git tag #查看全部标签 git tag v1.0 #给最新commit打标签 git tag v0.9 commit-id #给指定历史commit打标签 git tag -a v1.1 -m "版本1.1发布说明" #带说明的标签 git show v1.0 #查看标签对应的提交详情 git tag -d v1.0 #删除本地标签 git push origin v1.0 #推送单个标签到远程 git push origin --tags #推送所有本地标签到远程 #删除远程标签 git push origin :refs/tags/v1.0

十五、多人协同开发流程

1. 开发者克隆仓库;

2. 开发新功能,新建feature/xxx本地分支开发;

3. 开发完成,push推送到远程feature分支;

4. 如果推送被拒绝:远程版本比本地新 →git pull拉取远程,本地解决冲突,再push;

5. 自测完毕,提交Pull Request/Merge Request,请求合并到目标分支;

6. 管理员代码评审,合并到目标分支;

7. 合并完成,删除临时feature分支。

规范:禁止直接在master主分支写代码,master只接受合并,保证主分支稳定。

十六、企业GitFlow分支模型

分支名称作用来源分支合并去向说明
master生产线上正式版本hotfix/release只读稳定分支,上线版本打tag,禁止直接修改
develop开发主分支,存放开发完成功能masterrelease所有feature开发完合并到此,开发环境使用
feature/*新需求/新功能开发分支developdevelop每个需求新建,开发完合并develop,上线后删除
release/*预发布/测试分支developdevelop + master提测给测试人员,测试环境、预发布环境;上线完成删除
hotfix/*线上紧急bug修复分支mastermaster + develop线上出故障,基于master创建,修复后同时合并master和develop,打完tag删除

GitFlow完整工作流

1. 新需求:基于develop创建feature/xxx分支开发;

2. feature开发完成合并回develop;

3. 一批需求完成,基于develop拉出release/v1.0交给测试;

4. release测试出bug在release分支修复;

5. 测试全部通过:release分别合并进master和develop;master打版本tag;删除release分支;

6. 线上出现紧急bug:从master拉hotfix/xxx修复;修复完同时合并master、develop,master打tag,删除hotfix。

补充:GitFlow只是一种分支模型,不是唯一标准;还有主干开发模式,企业根据团队规模灵活选择。

十七、开发环境概念

1. 开发环境:开发人员日常调试,代码来自develop分支;

2. 测试环境:测试人员测功能,来自release分支;

3. 预发布环境:配置和线上生产完全一致,上线前最后验证;

4. 生产环境:面向真实用户线上服务,来自master分支。

十八、常见面试简答题

1. 工作区、暂存区、版本库三者关系?

1)工作区:我们实际操作代码的本地文件夹,日常编写修改代码的位置。

2)暂存区(Stage/Index):相当于一个临时中转站,位于.git/index。执行git add,将工作区的改动放到暂存区。

3)版本库(本地仓库):.git目录,Git真正保存所有历史版本数据;执行git commit,将暂存区内容提交存入版本库,生成一条版本记录。

完整流程:工作区 → git add → 暂存区 → git commit → 版本库

新创建文件仅仅停留在工作区,Git不会跟踪,必须经过git add放到暂存区,再git commit提交版本库,才算纳入版本管理。

2. git reset --soft / --mixed / --hard区别,--hard风险?

git reset移动HEAD分支指针,回退到指定历史版本。三种模式对三个区域影响各不相同:

1) --soft:只移动版本库HEAD指针。暂存区、工作区内容保持原样不变。
场景:想重新commit,不需要改动代码,只重新生成一次提交记录。

2) --mixed(默认模式,可以省略不写):版本库回退,暂存区同步回退,工作区不变。
场景:提交之后,想撤销提交,修改完代码再重新提交,最常用。

3) --hard:版本库回退、暂存区回退、工作区文件也强制回退到历史版本。

⚠️--hard风险:
工作区所有未提交的修改会直接永久丢失,无法恢复;
如果代码已经push推送到远程仓库,再本地reset --hard,本地和远程版本不一致,后续推送会报错,多人协作环境严禁随意使用。

参数版本库暂存区工作区
--soft回退不变不变
--mixed(默认)回退回退不变
--hard回退回退回退(数据丢失风险)

3. git stash什么时候用?

使用场景:当前分支代码写了一半,半成品,不能commit提交;但是需要临时切换其他分支去修复bug或者处理紧急任务。

直接切换分支,未提交的修改会跟随到另一个分支,造成代码混乱。

• git stash:把当前工作区、暂存区的修改打包储藏,让工作目录恢复干净,此时可以安全切换分支;

• 处理完别的工作切回原分支,git stash pop恢复之前半成品代码继续开发。

补充要点:

1)stash只保存在本地,不会上传远程仓库;

2)默认不会保存还没有git add的全新文件;

3)pop恢复同时删除储藏记录;apply恢复但是保留储藏备份。

4. 什么是冲突,冲突如何解决?

什么是冲突

两个不同分支,对同一个文件的同一行代码都做了修改,Git无法自动判断采用哪一份代码,合并时就产生冲突。

冲突解决完整步骤

1. Git提示CONFLICT(content),文件内部自动写入冲突标记:

<<<<<<< HEAD // 当前分支代码 此处是当前分支内容 ======= // 分割线 此处是被合并过来分支代码 >>>>>>> dev // 被合并分支名称

2. 打开文件,手动删除 <<<<<< ===== >>>>>> 这些标记,把代码编辑成最终需要的正确版本;

3. 修改完毕,执行git add 文件名,标记冲突已经解决;

4. 执行git commit完成本次合并。

如果想放弃本次合并,恢复合并之前状态:git merge --abort

5. Fast‑forward和--no‑ff合并区别?

Fast‑forward(快进合并,Git默认行为)

条件:master分支没有产生任何新提交。
合并dev分支的时候,Git不产生新commit,仅仅直接把master指针移动指向dev最新提交。

缺点:

1. 没有新增合并提交记录;

2. 如果后续删除dev分支,整个分支开发历史痕迹直接消失,无法看出曾经进行过一次分支合并。

--no‑ff(禁用快进合并)

git merge --no‑ff -m "合并dev分支" dev

无论是否满足快进条件,强制生成一条全新merge提交节点。

✅优点:完整保留分支历史,可以清晰看到什么时候做的分支合并;企业正式项目推荐使用。

简单总结:
fast‑forward:不生成新commit,历史干净,但丢失分支痕迹;
--no‑ff:生成专门合并commit,保留完整分支演进轨迹。

6. GitFlow各个分支用途?feature/release/hotfix/master/develop

1) master(主分支)
线上生产稳定版本,只读,禁止直接在这里写代码。每一次上线版本都会打tag标签,代表线上发布版本。

2) develop(开发主分支)
所有开发功能完成之后合并到此分支,作为开发环境基准分支。所有新功能从develop拉出。

3) feature/*(功能分支)
每个新需求新建一条feature分支,从develop分支拉出;功能开发测试完成合并回develop;上线之后该分支删除。

4) release/*预发布/测试分支
一批功能开发完毕,从develop分支拉出release分支,交给测试人员。只修改bug,不新增功能。测试全部通过,同时合并到master和develop;master打版本tag,之后删除release分支。

5) hotfix/*热修复分支
线上master出现严重紧急bug。直接从master分支拉出hotfix分支修复故障;bug修复完成,同时合并回master(打tag上线)与develop,保证下一个版本也包含bug修复代码,处理完毕删除hotfix

口诀:feature做功能,release给测试,hotfix救线上,develop汇总开发,master保存线上稳定版本。

7. git reflog作用?

git log只能看到当前分支可到达的commit提交记录。
当执行git reset版本回退,旧commit节点在git log会消失看不见。

git reflog记录本地仓库全部操作历史:每一次commit、reset、merge、checkout,所有HEAD指针移动记录全部保存。

✅核心用途:找回因为reset --hard误操作丢失掉的commit版本。
拿到丢失commit‑id,执行git reset --hard commit‑id,恢复被回退丢掉的代码。

⚠️注意:reflog只存在本机本地,不会同步远程仓库。

8. .gitignore作用,哪些文件一般需要忽略?

作用

.gitignore告诉Git哪些文件、文件夹不需要纳入版本控制,Git会直接忽略,不会追踪。

通常需要忽略的文件类型

1. 编译产物:build/、Debug/、*.o、*.so、可执行程序,编译生成的中间文件;

2. 日志文件:*.log程序运行日志;

3. 本地配置文件:*.ini、本地私有配置,每个人本地配置不一样,不要提交仓库;

4. IDE编辑器自动生成文件:.vscode/、.idea/;

5. 操作系统生成的垃圾文件:.DS_Store(Mac);

6. 大型二进制资源:数据库dump、临时备份文件。

示例.gitignore

build/ *.log .vscode/ *.ini .DS_Store

补充:如果文件已经被Git跟踪,此时修改.gitignore不会自动忽略该文件;需要先删除缓存。强制提交被忽略文件命令:git add -f 文件名。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询