Git学习
Git 使用技巧汇总
测试 git diff 功能
git diff:查看未暂存文件与上次提交之间的差异。git diff --staged:查看已暂存文件与上次提交之间的差异。
✅ 一句话总结:如果文件在未暂存区,使用 git diff;如果文件已暂存,使用 git diff --staged。
提交操作
git commit -a:跳过git add阶段,一键暂存并提交所有修改。git commit --amend:撤销最近一次提交,并允许:- 使用
git add补充遗漏的文件; - 编辑或保留原有的提交信息后重新提交。
- 使用
🔁 适用于刚提交完发现还有文件没添加,或者需要修改提交信息的情况。
文件重命名操作
git mv <原文件名> <新文件名>:用于重命名 Git 跟踪的文件。
示例:
git mv test1.txt test.txt
撤销暂存操作
git reset HEAD <文件名>:取消某个文件的暂存状态。
示例:
git reset HEAD README.md
📌 常用于误将某些文件加入暂存区后想将其移出的情况。
放弃本地修改
git restore <文件名>:放弃对该文件的所有本地修改。
⚠️ 注意:该操作不可逆,请确保确实不需要这些修改后再执行。
分支切换与紧急修复流程
假设你现在正在解决问题53,当前处于 iss53 分支上,而 main 分支突然出现了问题,需要马上修复。
✅ 处理步骤如下:
-
切换回
main分支:git switch main -
创建一个临时分支
hotfix来修复问题:git checkout -b hotfix -
修复完成后,提交更改。
-
切换回
main分支并合并修复内容:git checkout main
git merge hotfix -
删除临时分支(问题已修复):
git branch -d hotfix -
回到
iss53分支继续开发:git switch iss53
合并冲突说明及解决方法
⚠️ 冲突原因
当 main 和 iss53 分支同时修改了同一个文件的相同部分(例如 README.md),Git 无法判断应该保留哪边的内容,就会提示冲突。
示例场景
- 在
main分支下修改了README.md并提交; - 然后切换到
iss53分支,在此分支下也修改了README.md并提交; - 最后切换回
main分支,尝试合并iss53,出现冲突。
🔧 解决步骤
-
打开冲突文件(如
README.md),你会看到类似如下内容:<<<<<<< HEAD
This is the content from main.
=======
This is the content from iss53.
>>>>>>> iss53 -
手动编辑文件,选择你想要保留的内容,删除冲突标记。
-
添加修改后的文件到暂存区:
git add README.md -
提交合并结果:
git commit -m "Fixed conflict"
💡 如何避免冲突?
- 保持分支同步:在修改前先拉取最新代码;
- 及时合并分支:避免两个分支长时间不合并;
- 明确分工:团队协作时尽量避免多人修改同一文件的关键区域;
- 使用 Pull Request 审查机制:提前发现潜在冲突。
✅ 实际测试说明
这是一个测试内容,当前文本是在 iss53 分支下编写完成的。之前已经与 main 分支合并。
按照预期,切换回 main 分支后,再合并 iss53 分支不会产生冲突,也就是说,在 main 分支下也能看到这段新增内容。
查看当前仓库的用户配置 😊
- 全局
- 本地
git config --global user.name
git config --global user.email
git config user.name
git config user.email
配置当前仓库的用户配置 🛠️
- 全局
- 本地
git config --global user.name "GlobalAuthor"
git config --global user.email "global@example.com"
# 不加 --local 参数(默认就是局部配置)
git config user.name "LocalAuthor"
git config user.email "local@example.com"
移除当前仓库的用户配置 🛠
- 全局
- 本地
# 移除全局用户配置
git config --global --unset user.name
git config --global --unset user.email
# 移除本地用户配置
git config --unset user.name
git config --unset user.email
切换作者推送代码 🔁
如果想要使用全局配置的作者信息进行推送,需要先删除局部(本地仓库)的作者配置。
- 删除本地仓库的用户配置:
# 进入你的仓库目录
cd your-repository
# 删除本地的用户配置
git config --unset user.name
git config --unset user.email
- 验证配置是否已删除:
# 查看当前仓库的用户配置(应该没有输出)
git config --local --list | grep user
# 查看生效的配置(应该显示全局配置)
git config --list | grep user
- 确认使用的是全局配置:
# 查看当前生效的用户信息
git config user.name
git config user.email
- 提交时的作者信息 删除本地配置后,新提交将使用全局配置的作者信息:
# 此时的提交将使用全局配置的作者
git commit -m "message"
GitHub 身份识别机制总结 📚
核心原理 ⚡
- 提交作者识别:基于 Git 提交中的
user.name和user.email - SSH 密钥作用:仅用于认证访问权限,不决定提交作者
场景分析 🎭
配置情况:
- 全局作者:A
- 局部作者:B(本地仓库配置)
- SSH 密钥:A 的密钥
- 仓库权限:通过 A 的密钥访问 C 的仓库
识别结果:GitHub 显示推送者为 B(局部配置优先)
关键命令 🔑
# 查看当前身份配置
git config user.name
git config user.email
# 查看提交身份
git var GIT_AUTHOR_IDENT
git log --pretty=format:"%an <%ae>" -1
最终效果 🎯
- 提交作者:B(局部配置)
- 推送权限:A(SSH 密钥认证)
- 仓库所有者:C(实际仓库拥有者)
解决 Key is already in use 问题 💡
- 为不同账户生成不同的密钥对
# 为用户A生成密钥
ssh-keygen -t rsa -b 4096 -C "userA@example.com" -f ~/.ssh/userA_key
# 为用户B生成密钥
ssh-keygen -t rsa -b 4096 -C "userB@example.com" -f ~/.ssh/userB_key
- 配置 SSH 配置文件区分不同账户
创建/编辑
~/.ssh/config文件:
# 用户A的配置
Host github-userA
HostName github.com
User git
IdentityFile ~/.ssh/userA_key
# 用户B的配置
Host github-userB
HostName github.com
User git
IdentityFile ~/.ssh/userB_key
- 克隆和推送时使用不同 Host
# 克隆用户A的仓库
git clone git@github-userA:username/repo.git
# 克隆用户B的仓库
git clone git@github-userB:username/repo.git
- 为现有仓库更改 remote URL
# 更改为用户A的配置
git remote set-url origin git@github-userA:username/repo.git
# 更改为用户B的配置
git remote set-url origin git@github-userB:username/repo.git
验证配置 ✅
# 测试连接用户A
ssh -T git@github-userA
# 测试连接用户B
ssh -T git@github-userB
这样就可以用不同的密钥管理不同账户的仓库访问权限。🎉
将本地新建分支推送到远端
git push -u origin your-branch-name
空信息的 commit
想要撤销 git commit -m "wrong commit"?
git commit --amend
告别混乱提交—— git add -p
遇到情况:
一天下来改了很多地方,但提交时却说不清具体改了什么,只能模糊地说“优化了一些代码”……
🔑 核心原则:小步提交(Small, Atomic Commits)
- 不要等“一天结束”才提交
- 每完成一个逻辑单元(如裁剪一个库、修复一个 bug),就立即提交
- 每次提交只做一件事,意图清晰、可追溯、易回滚
🛠 实战利器:git add -p(交互式暂存)
当已经改了一堆内容,git add -p 能实现从混乱中理出多个清晰提交。
使用步骤:
- 查看改动
git status # 查看哪些文件被修改
git diff # 预览所有变更(通常很乱) - 交互式选择要暂存的代码块
git add -p
Git 会逐块(hunk)询问你是否暂存:
| 按键 | 含义 | 说明 |
|---|---|---|
y | yes | ✅ 暂存当前 hunk(推荐常用) |
n | no | ❌ 跳过当前 hunk,不暂存 |
q | quit | 🛑 退出交互模式,不再处理剩余 hunks(已选的仍会暂存) |
a | all | ✅ 暂存当前及所有后续 hunks(不再询问) |
d | do not stage this hunk and skip the rest | ❌ 不暂存当前 hunk,并跳过文件中所有剩余 hunks |
j | leave this hunk undecided, see next undecided | ⏭️ 跳到下一个“未决定”的 hunk |
J | leave this hunk undecided, see next | ⏭️ 暂不决定,先看下一个 hunk(稍后回看) |
g | select a hunk to go to | 🔍 输入编号直接跳转到指定 hunk |
/ | search for a hunk matching regex | 🔍 用正则表达式搜索 hunk |
s | split | 🔪 将当前大 hunk 拆分成更小的 hunks(如果可能),便于精细选择 |
e | edit | ✏️ 手动编辑当前 hunk(高级!可删减行、修改内容) |
p | print the current hunk | 🖨️ 重新打印当前 hunk(用于确认) |
? | help | ❓ 显示帮助信息(即当前提示) |
- 分主题多次提交
# 第一次:只提交 cJSON 裁剪
git add -p
git commit -m "perf(cjson): remove unused print functions to save 8KB Flash"
# 第二次:只提交 OLED 字符优化
git add -p
git commit -m "refactor(oled): delete unused ASCII font glyphs"
# 第三次:调整栈大小
git add -p
git commit -m "config(stack): reduce Stack_Size to 2KB"
💡 结果:一次“混乱修改” → 多个独立、可读、可测试的提交!
✍️ 用「约定式提交」规范
格式:
<type>(<scope>): <subject>
<body>
| 类型 | 说明 |
|---|---|
feat | 新功能 |
fix | 修复 bug |
perf | 性能/体积优化 |
refactor | 重构(不改变行为) |
chore | 杂务(配置、依赖更新等) |
✅ 示例:
perf(cjson): remove unused print functions to save 8KB Flash
- Deleted print_number, cJSON_Print, and related helpers
- Only JSON parsing retained
- RO-data reduced from 14KB to 6KB
🌟 为避免再次陷入混乱
| 技巧 | 说明 |
|---|---|
| 任务前置规划 | 写代码前用 // TODO: [TASK] ... 划分逻辑单元 |
| 使用特性分支 | git checkout -b feat/xxx 隔离大改动 |
| 预览再提交 | git diff --cached 确认即将提交的内容 |
| 善用工具 | VS Code / GitKraken 支持可视化 hunk 选择,但 git add -p 最通用 |
