跳到主要内容
Cowers://KNOWLEDGE
全部文章
工具链

Git 使用指南

掌握 Git 是开发者的必备技能。它不只是保存代码的工具,更是一套跟踪变更、协同合作的工作流。 本文档统一采用 Git 2.23+ 的现代命令体系(git switch / git restore),不再使用旧式 git…

Git 使用指南

说明 掌握 Git 是开发者的必备技能。它不只是保存代码的工具,更是一套跟踪变更、协同合作的工作流。 本文档统一采用 Git 2.23+ 的现代命令体系(git switch / git restore),不再使用旧式 git checkout 写法。 场景假设:远程仓库名为 origin,主分支为 main(Gitee/GitHub 均适用,若主分支为 master 请自行替换)。


零、极简核心概念

先把这几个名词印在脑子里,后面就会非常顺畅:

  • 仓库 (Repository):项目的"档案柜",Git 在里面记录所有文件的每次改动。
  • 工作区 (Workspace):你电脑里正在编辑的文件夹,肉眼可见的代码。
  • 暂存区 (Staging Area / Index):一个"购物车",你决定哪些修改要放入下一次的存档(提交)里。
  • 提交 (Commit):按下快门。给暂存区的文件拍一张快照,并附上说明信息,是版本历史的节点。
  • 分支 (Branch):一条平行时间线。你可以在分支上大胆实验新功能,完全不影响主线的稳定代码。

三个区域的关系,也是后面"后悔药"的基础:

工作区(改了没 add) → 暂存区(add 了没 commit) → 版本库(commit 了)

初始化与身份配置(只需做一次)

git init                              # 在项目根目录生成隐藏的 .git,Git 开始接管版本记录
# 配置全局身份(所有仓库通用)
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
 
# 只给当前仓库配置身份(覆盖全局)
git config user.name "你的名字"
git config user.email "你的邮箱"
 
# 查看当前身份配置
git config --global user.name
git config --global user.email

一、拉取仓库

1.1 克隆仓库

# 完整克隆(默认克隆所有分支的历史,检出默认分支)
git clone https://gitee.com/xxx/stusys.git
 
# 克隆到指定目录
git clone https://gitee.com/xxx/stusys.git my-project
 
# 浅克隆:只拉取最近 1 次提交(仓库大、只想看代码时提速)
git clone --depth 1 https://gitee.com/xxx/stusys.git
 
# 克隆并直接切到指定分支
git clone -b dev https://gitee.com/xxx/stusys.git

1.2 拉取更新:fetch vs pull

命令 作用 是否修改工作区
git fetch 只下载远程的新提交到本地(更新 origin/main 等远程跟踪分支) ❌ 不动你的代码
git pull fetch + 合并到当前分支 ✅ 会改动当前分支
# 安全做法:先看后合
git fetch origin
git log HEAD..origin/main --oneline   # 看看远程比本地多了什么
git diff --stat origin/main           # 看和远程主分支有哪些文件差异
git merge origin/main                 # 确认没问题再合并
 
# 快捷做法
git pull                              # = fetch + merge
git pull --rebase                     # = fetch + rebase,历史更线性

pull 的三种策略(本地和远程分叉时)

git config pull.ff only      # 只允许快进,分叉就报错(最保守)
git config pull.rebase true  # 分叉时 rebase,历史一条直线(推荐个人开发)
git config pull.rebase false # 分叉时 merge,产生合并提交(默认)

报错 fatal: Need to specify how to reconcile divergent branches 就是没配这个。

1.3 关联远程仓库(本地已有项目)

git init
git remote add origin https://gitee.com/xxx/stusys.git
git remote -v                         # 查看远程地址
git remote set-url origin <新地>     # 修改远程地址(如 HTTPS 换 SSH)
git push -u origin main               # -u 建立跟踪关系,以后可直接 git push

二、分支操作

不直接在 main(或 master)分支上写代码,是成熟开发者的标志。

2.1 查看分支

git branch          # 本地分支
git branch -r       # 远程分支
git branch -a       # 全部分支
git branch -vv      # 显示本地分支与远程的跟踪关系 + 领先/落后情况

2.2 创建与切换分支

# 现代写法(推荐)
git switch -c feature/score-api       # 创建并切换
git switch dev                        # 切换到已有分支
git switch -                          # 切回上一个分支
 
# 基于远程分支创建本地分支(自动建立跟踪)
git switch -c dev origin/dev
# 若本地不存在同名分支,可直接:
git switch dev                        # git 会自动匹配 origin/dev

命名规范建议 feature/xxx 新功能、fix/xxx 修 bug、refactor/xxx 重构、hotfix/xxx 紧急修复。

2.3 更新同步主分支(核心工作流)

场景:在 feature 分支开发期间,main 有了新提交,需要同步过来。

# 方式一:merge(安全,保留完整历史,会产生一个合并提交)
git switch feature/score-api
git fetch origin
git merge origin/main
 
# 方式二:rebase(历史干净,像"把你的提交挪到最新 main 之后重演一遍")
git switch feature/score-api
git fetch origin
git rebase origin/main
# 冲突时:改完文件 → git add . → git rebase --continue
# 想放弃:git rebase --abort
对比 merge rebase
历史形状 有分叉和合并节点 一条直线
是否改写提交 是(commit id 会变)
适用场景 团队共享分支 个人 feature 分支
铁律 已推送到远程、有人基于它开发的提交,不要 rebase
# 同步完成后,把 feature 合回 main(通常走 PR,本地操作如下)
git switch main
git pull
git merge feature/score-api
git push

2.4 删除与重命名

git branch -d feature/score-api       # 删除已合并的分支
git branch -D feature/score-api       # 强制删除(未合并也删)
git push origin --delete feature/xxx  # 删除远程分支
git branch -m 旧名 新名                # 重命名
git fetch --prune                     # 清理远程已删除、本地还残留的跟踪分支

三、提交与推送代码

3.1 标准流程

git status                    # 查看改动状态(养成习惯,每步之前都看一眼)
git diff                      # 工作区 vs 暂存区的差异
git diff --staged             # 暂存区 vs 上次提交的差异
 
git add app/routers/score.py  # 添加指定文件
git add .                     # 添加全部改动(谨慎,新手建议先用 status 确认)
git add -p                    # 交互式挑选代码块暂存(精细控制)
 
git commit -m "feat: 新增成绩查询接口"
git push                      # 已建立跟踪关系时
git push -u origin feature/x  # 首次推送新分支

3.2 修补提交

# 刚提交完发现漏了文件 / 提交信息写错(仅限还没 push!)
git add 漏掉的文件
git commit --amend -m "新的提交信息"
git commit --amend --no-edit          # 只补文件,不改信息

3.3 暂存现场:stash

场景:改到一半要紧急切分支,又不想提交半成品。

git stash                             # 存起来(默认不含未跟踪文件)
git stash -u                          # 连未跟踪的新文件一起存
git stash list                        # 查看暂存列表
git stash pop                         # 恢复最近一次并删除记录
git stash apply stash@{1}             # 恢复指定记录但保留
git stash drop stash@{0}              # 删除指定记录

3.4 推送相关

git push --force-with-lease           # rebase 后推送用它,比 --force 安全
                                      # (远程若有别人的新提交会拒绝,避免覆盖队友代码)
git push origin v1.0                  # 推送标签
git push origin --tags                # 推送全部标签

四、处理冲突

当两个人改了同一个文件的同一行,git pullmerge/rebase 时会报 CONFLICT

  1. 打开报红的文件,你会看到类似标记:
    <<<<<<< HEAD
    你写的代码
    =======
    别人写的代码
    >>>>>>> 分支名
  2. 手动编辑,删掉 <<< === >>> 标记,保留你们协商后最终想要的正确代码。
  3. 保存文件,执行:
    git add .
    git commit -m "fix: resolve merge conflict"   # merge 冲突
    # 若是 rebase 冲突,则用:git rebase --continue

五、恢复代码:版本管理操作

5.1 三个区域对应三种"后悔药"

后悔场景 命令
改乱了,还没 add,想丢弃 git restore 文件名
add 了,想撤回到工作区(改动保留) git restore --staged 文件名
commit 了,想撤销提交但保留改动 git reset --soft HEAD~1
commit 了,想彻底抹掉提交和改动 git reset --hard HEAD~1 ⚠️
提交已推送,想公开撤销 git revert <commit-id>

5.2 restore 详解

git restore .                         # 丢弃工作区所有未暂存的改动 ⚠️
git restore --staged .                # 全部撤出暂存区
git restore --source HEAD~2 app.py    # 把某文件恢复到 2 个版本前的样子

5.3 reset 三种模式

git reset --soft HEAD~1    # 撤销 commit,改动留在【暂存区】
git reset --mixed HEAD~1   # 撤销 commit,改动留在【工作区】(默认模式)
git reset --hard HEAD~1    # 撤销 commit,改动【全部丢弃】⚠️ 危险

reset vs revert

  • reset:改写历史,只用于还没推送的本地提交
  • revert:生成一个"反向提交"抵消旧提交,历史不变,已推送的用它
git revert abc1234           # 撤销某次提交
git revert HEAD --no-edit    # 撤销最近一次,不弹编辑器

清空本地分支,重新锚定远程主分支 本地改乱了想彻底重来,直接对齐远程 main:

git fetch origin
git reset --hard origin/main          # ⚠️ 丢弃本地所有提交和改动
git clean -fd                         # 删除未跟踪的文件和目录

5.4 终极后悔药:reflog

场景:reset --hard 之后发现删错了。

git reflog                    # 记录 HEAD 的每一次移动(哪怕提交"被删了")
# 找到误删前的 commit id,例如 e5f6a7b
git reset --hard e5f6a7b      # 满血复活

5.5 摘取提交:cherry-pick

场景:只想把 dev 分支上的某一个提交搬到 main,不想整个合并。

git switch main
git cherry-pick abc1234              # 摘一个
git cherry-pick abc1234 def5678      # 摘多个
git cherry-pick abc1234..fff9999     # 摘一个区间(不含起点)
# 冲突处理:改完 → git add . → git cherry-pick --continue

5.6 查看历史

git log --oneline --graph --all      # 图形化查看全部分支历史
git log -p app/models.py             # 查看某文件的修改内容历史
git blame app/models.py              # 逐行查看是谁最后改的
git show abc1234                     # 查看某次提交的详情

六、工作树(git worktree)

解决的问题: 想同时打开两个分支的代码(比如一边开发 feature、一边紧急修 main 上的 bug),传统做法要 stash → switch → 改完 → switch 回来 → stash pop,很繁琐。worktree 允许同一个仓库检出到多个目录,互不干扰。

6.1 基本操作

# 当前在 ~/stusys(main 分支),新建一个工作树放 hotfix 分支
git worktree add ../stusys-hotfix -b hotfix/login-bug
 
# 基于新分支创建工作树(分支不存在时)
git worktree add -b hotfix/login-bug ../stusys-hotfix main
 
# 现在:
# ~/stusys          → main 分支,继续开发
# ~/stusys-hotfix   → hotfix 分支,另开一个编辑器窗口修 bug

6.2 管理工作树

git worktree list                     # 列出所有工作树
git worktree remove ../stusys-hotfix  # 用完删除(目录也会被删)
git worktree prune                    # 清理已被手动删除目录的残留记录

6.3 注意事项

使用限制

  1. 同一个分支不能同时被两个工作树检出——想在别处看 main,git worktree add ../tmp main 会报错,需用 --detach 分离头指针模式。
  2. 所有工作树共享同一个 .git 仓库数据,提交历史、stash、配置是共通的;但工作区和暂存区各自独立。
  3. 虚拟环境、node_modules.env 这类不入库的文件不会出现在新工作树里,需要重新创建。

6.4 典型工作流示例

# 正在 feature 分支写代码,突然 main 上有紧急 bug
git worktree add -b hotfix/urgent ../stusys-hotfix origin/main
cd ../stusys-hotfix
# ...修复、提交、推送、提 PR...
git push -u origin hotfix/urgent
cd ../stusys                          # 回到原目录,feature 的现场原封不动
git worktree remove ../stusys-hotfix  # 修完清理

七、提交信息规范(Conventional Commits)

为了让 git log 看起来像文档而不是流水账,推荐使用约定式提交:

  • feat: 新功能
  • fix: 修 bug
  • docs: 文档更新
  • style: 代码格式(不影响逻辑)
  • refactor: 重构(既不是新功能也不是修 bug)
  • test: 增加测试
  • chore: 杂项

举例:git commit -m "feat: add captcha validation on login page"


八、首次上传项目到 GitHub

# 1. 绑定远程仓库
git remote add origin https://github.com/你的用户名/仓库名.git
 
# 2. 保证本地分支名和远程一致
git branch -M main
 
# 3. 推送并建立跟踪
git push -u origin main

Token 认证(HTTPS 推送) 推送时弹出账号密码:用户名填 GitHub 用户名,密码填 Personal Access Token(不是登录密码)。 Token 获取路径:头像 → Settings → Developer settings → Personal access tokens → Tokens (classic)


附:高频命令一页总结

目的 命令
克隆 git clone <url>
拉取(先看后合) git fetchgit merge origin/main
创建并切分支 git switch -c feature/xxx
同步主分支 git fetchgit rebase origin/main
提交三连 git add .git commit -m "..."git push
暂存现场 git stash / git stash pop
丢弃工作区改动 git restore .
撤销 commit 保留改动 git reset --soft HEAD~1
撤销已推送提交 git revert <id>
找回误删提交 git refloggit reset --hard <id>
摘取单个提交 git cherry-pick <id>
多目录多分支 git worktree add <路径> <分支>

可视化工具辅助 命令行最强,但想直观感受分支树和差异,可搭配 VS Code 内置 Git 插件GitHub Desktop。观察一段时间分支合并图,会对 Git 的运行逻辑有更深理解。