一文吃透Git:本地操作|冲突处理|远程协作|GitFlow工作流详解

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


一、什么是版本控制器

1.1 痛点

日常写文档、写代码,为了防止改错丢失,手动复制多份文件:报告‑v1、报告‑v2、报告‑最终版、报告‑究极版。

问题:版本多,记不清每个版本改了什么,多人协同修改文件很难合并。

1.2 版本控制器

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

重要特性:

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

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

二、Git安装与基础配置

2.1 各平台安装命令

  1. CentOS7
bash 复制代码
sudo yum -y install git
git --version #查看版本
  1. Ubuntu
bash 复制代码
sudo apt-get install git -y
git --version
  1. Windows:下载安装包图形化安装。

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

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

bash 复制代码
# 设置用户名和邮箱
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管理的文件夹。

bash 复制代码
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

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

5.2 提交到本地版本库 git commit

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

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

5.3 查看提交日志 git log

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

5.4 查看状态与差异

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

六、版本回退 reset 命令

6.1 reset三种模式

bash 复制代码
git reset [--soft | --mixed | --hard] [版本标识]

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

6.2 版本定位写法

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

6.3 找回丢失commit:git reflog

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

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

七、撤销修改的三种场景

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

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

bash 复制代码
git restore 文件名
# 旧写法:git checkout -- 文件名 (--不能省略!)

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

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

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

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

直接版本回退

bash 复制代码
git reset --hard HEAD^

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

八、删除文件

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

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

bash 复制代码
git rm 文件名
git commit -m "删除xxx文件"

误删恢复:git restore 文件名

九、Git分支管理

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

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

9.1 分支基础命令

bash 复制代码
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提交,完整保留分支历史痕迹。

bash 复制代码
git merge --no-ff -m "合并dev分支" dev

十、合并冲突处理

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

  1. git提示冲突,文件内标记冲突标记
bash 复制代码
<<<<<<< HEAD    // 当前分支内容
当前分支代码
=======        //分割线
被合并分支代码
>>>>>>> dev1    //被合并分支名
  1. 手动打开文件,删掉<<<<<< ===== >>>>>>标记,编辑成最终想要的代码

  2. git add .标记冲突解决

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

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

十一、stash 工作现场储藏

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

bash 复制代码
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切回来,再把代码恢复出来。

每条命令详解

bash 复制代码
git stash                 # 保存当前工作现场,工作区变干净

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

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

bash 复制代码
git stash list            # 查看所有储藏的现场

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

输出示例:

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

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

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

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

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

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

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

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

bash 复制代码
git stash drop stash@{0}  # 删除指定一条储藏
git stash clear           # ⚠️清空全部stash备份
bash 复制代码
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示例内容

bash 复制代码
*.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. 生成密钥对:
bash 复制代码
ssh-keygen -t rsa -C "你的注册邮箱"
# 一路回车,生成 ~/.ssh/id_rsa(私钥,保密) id_rsa.pub(公钥,粘贴到gitee)
  1. 复制id_rsa.pub全部内容,粘贴到gitee账号‑SSH公钥设置。

13.2 远程仓库基础命令

bash 复制代码
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 本地分支关联远程分支

bash 复制代码
# 本地新建dev分支,关联origin/dev远程分支
git checkout -b dev origin/dev

# 设置已有本地分支追踪远程分支
git branch --set-upstream-to=origin/dev dev

查看全部本地+远程分支

bash 复制代码
git branch -a
git branch -r #只看远程分支

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

bash 复制代码
git remote prune origin

十四、tag标签管理

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

bash 复制代码
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 | 开发主分支,存放开发完成功能 | master | release | 所有feature开发完合并到此,开发环境使用 |
| feature/* | 新需求/新功能开发分支 | develop | develop | 每个需求新建,开发完合并develop,上线后删除 |
| release/* | 预发布/测试分支 | develop | develop + master | 提测给测试人员,测试环境、预发布环境;上线完成删除 |
| hotfix/* | 线上紧急bug修复分支 | master | master + 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提交版本库,才算纳入版本管理。

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

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

1) --soft:只移动版本库HEAD指针。暂存区、工作区内容保持原样不变。

场景:想重新commit,不需要改动代码,只重新生成一次提交记录。

2) --mixed(默认模式,可以省略不写):版本库回退,暂存区同步回退,工作区不变。

场景:提交之后,想撤销提交,修改完代码再重新提交,最常用。

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

⚠️--hard风险:

工作区所有未提交的修改会直接永久丢失,无法恢复;

如果代码已经push推送到远程仓库,再本地reset --hard,本地和远程版本不一致,后续推送会报错,多人协作环境严禁随意使用。

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

  1. git stash什么时候用?

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

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

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

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

补充要点:

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

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

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

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

什么是冲突

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

冲突解决完整步骤

  1. Git提示CONFLICT(content),文件内部自动写入冲突标记:
bash 复制代码
<<<<<<< HEAD     // 当前分支代码
此处是当前分支内容
=======         // 分割线
此处是被合并过来分支代码
>>>>>>> dev      // 被合并分支名称
  1. 打开文件,手动删除 <<<<<< ===== >>>>>> 这些标记,把代码编辑成最终需要的正确版本;

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

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

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

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

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

条件:master分支没有产生任何新提交。

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

缺点:

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

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

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

bash 复制代码
git merge --no‑ff -m "合并dev分支" dev

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

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

简单总结:

fast‑forward:不生成新commit,历史干净,但丢失分支痕迹;

--no‑ff:生成专门合并commit,保留完整分支演进轨迹。

  1. 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保存线上稳定版本。

  1. 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只存在本机本地,不会同步远程仓库。

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

作用

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

通常需要忽略的文件类型

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

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

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

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

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

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

示例.gitignore

bash 复制代码
build/
*.log
.vscode/
*.ini
.DS_Store

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

相关推荐
2601_962218612 小时前
万象生鲜系统业财一体化底层打通技术自动生成经营账单
大数据·数据库·人工智能·python·算法
Easy_API3 小时前
从“有多少卡“到“卖多少 Token“:算力的标尺正在换
大数据·人工智能·深度学习
末央&4 小时前
GIT工具的基础指令与使用
git
移动云开发者联盟4 小时前
中国移动发布全链条算力服务成果
大数据
晓窗科技4 小时前
口碑好的AI基座服务商
大数据·人工智能·python
和裕4 小时前
蜂窝板 vs 七层瓦楞重型纸箱:大件工业设备运输性能与成本全对比
大数据·运维·网络·人工智能·算法
ACP广源盛139246256735 小时前
国产 PCIe2.1 交换芯片 IX6024:低成本轻量化端侧 AI IO 扩展选型解析
大数据·人工智能·硬件架构·pcie·国产芯片
小王毕业啦5 小时前
2012-2024年 机构投资者实地调研数据 xlsx
大数据·人工智能·数据挖掘·数据分析·社科数据·实证分析·经管数据
制造业的搬运工5 小时前
智能家居工控PCB可靠性检测规范与制程管控实践
大数据·网络·人工智能·制造·pcb工艺
2601_962218617 小时前
万象生鲜系统订单全生命周期状态同步技术实现业务可视
大数据·数据库·人工智能·python·算法