git

说明:
- workspace:工作区
- staging area:暂存区
- local repository:本地仓库
- remote reposiory:远程仓库
git pull
git pull是用于从远程仓库拉去最新代码并合并到本地分支,它本质是两个命令的组合:git fetch和git merge。
git fetch用于从远程仓库拉去最新代码,但不会修改你的当前工作区代码 git merge将下载下来的远程分支代码合并到本地分支。 git pull命令的执行顺序是:git fetch -> git merge。 如果合并过程中出现冲突,用户需要手动解决冲突,然后提交合并后的代码。 如果合并过程中没有冲突,用户直接提交合并后的代码。
冲突处理
当本地修改与远程代码修改了同一文件的相同位置时,会触发冲突。 用户需要手动解决冲突,寻找 <<<<<<<、======= 和 >>>>>>> 标记,手动删改代码并保存
git push -u
-u是--set-upstream的简写,推送的同时,把本地分支和远程分支关联起来
git push -u origin <branch-name>第一次推送一个新分支时要带上-u,它做了两件事:
- 把本地分支推送到远程的
origin/<branch-name> - 记录这个本地分支的上游分支(upstream),也就是告诉git「以后这个本地分支对应哪个远程分支」
关联好之后,后续在这个分支上直接
git push
git pull就行,不用再写origin <branch-name>,git会自动找到上游分支
查看本地分支和上游分支的对应关系
git branch -vv输出里带[origin/main]的,就是已经关联过上游的分支
如果推送时看到
fatal: The current branch xxx has no upstream branch.说明当前分支还没设置上游,加上-u重新推一次即可
git merge git rebase
git merge
创建一个新的合并提交,将两个历史连接在一起
假设你从main分支切出feature分支,此时main上也有了新的提交
C3---C4 (feature)
/
C1---C2---C5 (main)执行git merge main(在feature分支),git会找到C4和C5的公共祖先C2,然后创建一个新的合并提交C6,将C4和C5连接在一起。
C3---C4------\
/ v
C1---C2-------C5---C6 (feature / main 合并点)git rebase
把当前分支的提交依次摘下,重新在目标分支的顶部重放
执行git rebase main(在feature分支)
git会把C3、C4临时保存为补丁,将feature指针指向C5,然后依次重新应用C3、C4
C1---C2---C5---C3'---C4' (feature 变基到了 main 顶部)branch
创建新分支并切换到该分支
git checkout -b <branch-name>查看所有分支
git branch查看远程分支
git branch -r合并分支
git merge <branch-name>删除分支
git branch -d <branch-name>删除远程分支
git push origin --delete <branch-name>git switch
Git 2.23 引入的命令,专门用来切换分支,把原本git checkout里「切换分支」的职责单独拆出来,语义更清晰
切换分支
git switch <branch-name>创建新分支并切换到该分支(相当于git checkout -b)
git switch -c <branch-name>切回上一个分支
git switch -和 checkout 的区别
| 命令 | 用途 |
|---|---|
git switch | 只用于切换分支 |
git checkout | 既能切换分支,也能恢复工作区文件 |
git checkout <branch>和git checkout <file>写法完全一样,容易误操作,所以官方把它拆成了git switch(切分支)和git restore(恢复文件)
reset
让当前分支的HEAD、暂存区、工作区,回退到某个历史提交的状态
工作区
↓ git add
暂存区
↓ git commit
本地仓库--soft
git reset --soft HEAD~1撤销最近一次commit,但是代码保留,而且放在暂存区
也就是你可以直接重新commit
--mixed
默认行为
git reset HEAD~1
git reset --mixed HEAD~1撤销commit,同时取消git add,但代码本身保留
--hard
最危险
git reset --hard HEAD~1commit回退,暂存区回退,工作区代码也直接回退
HEAD~1
git reset --soft HEAD~1HEAD表示当前所在提交,HEAD~3表示上上上个提交。
A ← B ← C ← D
↑
HEAD相当于直接回退到A提交的状态
也可以直接指定commit
git log --oneline查看hash值后,直接指定commit
revert
新增一个提交,把某次提交的修改抵消掉
如果已经上传上去后,别的人已经基于这个提交做了修改,直接把提交干掉,会产生很多麻烦
git revert HEAD
撤销最新的一次提交
C:
修改了 a.java
增加了 b.java
删除了 c.java那么revert C会尝试
恢复 a.java
删除 b.java
恢复 c.java这个和HEAD~1不一样
HEAD = C
HEAD~1 = B
HEAD~2 = A选择
我要撤销修改
│
┌────────┴────────┐
│ │
还没有 push 已经 push
│ │
reset 很方便 公共分支?
│ │
│ ┌──────┴──────┐
│ │ │
│ 是 否
│ │ │
│ revert 看情况
│
resetworkflow
| 分支 | 寿命 | 从哪拉 | 合并回 | 何时用 |
|---|---|---|---|---|
| main/master | 长期 | 初始 | - | 生成环境代码 |
| develop | 长期 | main | main | 开发集成分支,feature完成后合入此 |
| feat/* | 临时 | develop | develop | 开发新功能,一个功能一个分支,完成就合并删除 |
| release/* | 临时 | develop | main+develop | 准备发布,冻结功能只改bug、写文档、版本号 |
| hotfix/* | 临时 | main | main+deve | 生产线上紧急bug修复,需立即上线 |
| bugfix/* | 临时 | develop | develop | 开发阶段非紧急bug修复,不影响发版节奏 |
假如你要开发新功能,通常从main分支切出一个新分支,例如feature分支,然后在feature分支上开发新功能。 开发完成后,合并feature分支到main分支。 最后,删除feature分支。
这样做的好处是:main始终保持可用,功能没开发完也不会影响别人,出问题直接删掉分支就行
1. 切出功能分支
先让main保持在最新状态,再从它切出分支
git switch main
git pull
git switch -c feature一定要先pull,如果基于过期的代码开发,合并时冲突会多很多
2. 开发并提交
git add .
git commit -m "✨ feat: 新增xxx功能"提交粒度尽量小,一个提交只做一件事,这样出问题时用revert单独撤销某一个提交就行
3. 推送并关联上游
第一次推送要带-u
git push -u origin feature4. 合并回 main
功能开发完、自测通过后,切回main合并
git switch main
git pull
git merge feature如果在团队里协作,这一步通常是提一个 PR / Merge Request,由别人 review 后在平台上点合并,而不是自己本地merge完直接push
如果main上别人也改到了同一个文件的同一位置,这里就会冲突,解决方式见前面的git pull
不想要合并提交、希望历史是一条直线的话,可以改用git rebase
5. 推送 main
git push6. 删除功能分支
合并完成后,feature的提交已经进到main里了,这个分支就没用了
删除本地分支
git branch -d feature删除远程分支
git push origin --delete feature-d是安全删除,如果分支还没合并会报错提醒你;确认真的不要了,可以用-D强制删除
整体流程
git switch main && git pull
git switch -c feature
↓ 开发、commit
git push -u origin feature
↓ 提 PR / code review
git switch main && git pull
git merge feature
git push
git branch -d featurecommit template
commit规范模板
<emoji> <type>(<scope>): <description>scope 表示影响的范围,例如user、order等。
| Emoji | type | 用途 | 示例 |
|---|---|---|---|
| ✨ | feat | 新功能 | ✨ feat: 新增购物车功能 |
| 🐛 | fix | 修 Bug | 🐛 fix: 修复订单提交失败 |
| 📝 | docs | 文档 | 📝 docs: 更新 README |
| ♻️ | refactor | 重构 | ♻️ refactor: 重构用户服务 |
| 🎨 | style | 样式/UI | 🎨 style: 优化登录页面样式 |
| ⚡ | perf | 性能优化 | ⚡ perf: 优化商品查询性能 |
| ✅ | test | 测试 | ✅ test: 添加用户登录测试 |
| 🔧 | chore | 杂项/配置 | 🔧 chore: 修改 Vite 配置 |
| 📦 | build | 构建/依赖 | 📦 build: 更新依赖版本 |
| 👷 | ci | CI/CD | 👷 ci: 添加 GitHub Actions |
| ⏪ | revert | 回滚 | ⏪ revert: 回滚用户模块修改 |