Git 用法速查
Git 是分布式版本控制系统:每个**仓库(repository)**保存项目的完整历史,可在本机或远程(如 GitLab / GitHub)协作。
核心概念
| 概念 | 说明 |
|---|---|
| 仓库 | 含.git目录的项目根目录,记录所有提交历史 |
| 工作区 | 你正在编辑的文件 |
| 暂存区(index) | git add后、等待git commit的快照 |
| 提交(commit) | 一次有说明的快照,有唯一哈希(如a1b2c3d) |
| 分支(branch) | 指向某条提交链的指针,常见main/develop |
| 远程(remote) | 另一份仓库的别名,默认常为origin |
工作区 ──git add──→ 暂存区 ──git commit──→ 本地仓库 ──git push──→ 远程仓库 ↑ ↑ git restore git checkout / switch本地仓库、远程仓库与分支(重点)
很多人混用「本地分支」和「远程分支」,其实 Git 里要分清三个层次。
1. 本地仓库 vs 远程仓库
| 本地仓库 | 远程仓库 | |
|---|---|---|
| 在哪 | 你机器上项目里的.git目录 | 服务器上(GitLab / GitHub 等) |
| 谁在用 | 你日常commit的地方 | 团队共享、push/pull的中转站 |
| 怎么关联 | git remote add origin <url>给远程起名 | 通过origin等名字被本地引用 |
gitremote-v# 看本地配置了哪些远程、对应 URLgitremote show origin# 远程有哪些分支、本地跟踪关系摘要git clone会同时:创建本地仓库、添加远程origin、并通常建好本地分支main(且已跟踪origin/main)。
2. 三种「分支」不要搞混
| 类型 | 名字示例 | 存在位置 | 作用 |
|---|---|---|---|
| 本地分支 | develop、feature/foo | 仅本地仓库 | 你切换上去写代码、commit的分支 |
| 远程分支 | 服务器上的develop | 远程仓库 | git push更新、git pull对齐的对象 |
| 远程跟踪分支 | origin/develop、origin/main | 本地仓库里的「只读书签」 | git fetch后更新的快照,不要直接在上面 commit |
关系可以理解为:
远程仓库 origin └── develop (远程分支,团队在服务器上看到的) 本地仓库 ├── develop (本地分支,你正在用的) └── origin/develop (远程跟踪分支,fetch 后反映远程 develop 在哪) ↑ └── 通过「上游 / upstream」与本地 develop 关联git fetch:只更新origin/*这类远程跟踪分支,不改你工作区里的本地分支。git pull:fetch+ 把远程跟踪分支合并/变基到当前本地分支(且通常要求已设置上游)。git push:把当前本地分支的提交推到其上游远程分支。
查看三类分支:
gitbranch# 仅本地分支,* 为当前分支gitbranch-r# 远程跟踪分支(origin/xxx)gitbranch-a# 本地 + 远程跟踪gitbranch-vv# 本地分支及其跟踪的上游(推荐)git branch -vv示例输出:
* develop a1b2c3d [origin/develop: ahead 1, behind 2] 最近一次提交说明 feature/foo e4f5g6h [origin/feature/foo] ... main 1111111 [origin/main: gone] ...[origin/develop]:本地develop跟踪远程origin/develop。ahead 1:本地比远程多 1 个提交,需要push。behind 2:远程比本地多 2 个提交,需要pull或merge/rebase。- 没有方括号:本地分支未设置上游跟踪。
git status在已跟踪分支上也会提示:
On branch develop Your branch is ahead of 'origin/develop' by 1 commit. (use "git push" to publish your local commits)3. 本地分支跟踪远程分支(upstream)
跟踪(upstream):告诉 Git「本地这个分支默认对应远程哪一个分支」。设置后可直接git pull、git push,不必每次写origin develop。
方式 A:首次推送时设置(最常用)
gitswitch-cfeature/my-work# 新建本地分支# ... 提交 ...gitpush-uorigin feature/my-work# 等价:git push --set-upstream origin feature/my-work-u/--set-upstream会:
- 在远程创建
feature/my-work(若还没有); - 把本地当前分支的上游设为
origin/feature/my-work。
当前分支首次推送也可写:
gitpush-uorigin HEAD方式 B:已有本地分支,事后指定上游
# 本地 develop 跟踪远程 origin/developgitbranch --set-upstream-to=origin/develop develop# 若当前已在 develop 上,可省略分支名gitbranch --set-upstream-to=origin/develop旧命令(仍可用):
gitbranch develop --set-upstream-to=origin/develop方式 C:从远程分支创建本地分支并自动跟踪
远程已有origin/develop,本地还没有develop:
gitfetch origingitswitch develop# 若本地无 develop、远程有 origin/develop,Git 会创建本地 develop 并跟踪它# 或显式指定(更明确)gitswitch-cdevelop--trackorigin/develop# 简写gitswitch-torigin/develop方式 D:克隆时默认跟踪
git clone后通常已有本地main,且跟踪origin/main,无需再设。
查看 / 修改 / 取消跟踪
gitbranch-vv# 看谁跟踪谁gitrev-parse --abbrev-ref --symbolic-full-name @{u}# 当前分支的上游名gitconfig branch.develop.remote# 查看 develop 的远程名gitconfig branch.develop.merge# 查看 develop 合并的远程分支 ref# 取消上游(之后 push/pull 需写全参数)gitbranch --unset-upstream develop4. 设置跟踪后的日常用法
gitpull# 从上游拉取并合并(或按配置 rebase)gitpush# 推到上游远程分支# 未设置上游时 push 会报错,需:gitpush-uorigin<本地分支名># 或gitpush origin HEAD:develop# 显式:本地 HEAD → 远程 develop(不自动设跟踪)fetch 与 pull 的区别(配合跟踪理解):
gitfetch origin# 更新 origin/*,本地 develop 不动gitmerge origin/develop# 手动把远程跟踪分支合进本地 developgitpull# = fetch + 合并到当前分支(针对 @{u})gitpull--rebase# = fetch + rebase 到当前分支5. 常见场景速查
| 场景 | 做法 |
|---|---|
| 新建功能分支并推到远程 | git switch -c feat/x→ 提交 →git push -u origin feat/x |
| 本地分支要对齐远程 develop | git fetch→git switch develop→git pull |
| 远程有新分支,本地还没有 | git fetch→git switch -t origin/release-1.14 |
| 本地分支名与远程不同 | git push -u origin local-name:remote-name |
| 看本地与远程差几个提交 | git branch -vv或git status |
| 上游设错了 | git branch --set-upstream-to=origin/正确分支名 |
6. 注意点
- 远程跟踪分支(
origin/main)是本地对远程的缓存,不能代替本地分支做开发;应在本地分支上commit,再push。 - 删除远程分支不会自动删本地分支:
git push origin --delete old-feature后,本地还可git branch -d old-feature。 - 多人协作时,推送前建议
git fetch+git pull(或rebase),减少push被拒(non-fast-forward)。
创建与获取仓库
# 在当前目录初始化新仓库gitinit# 从远程克隆(会多一个 origin 远程)gitclone https://example.com/group/project.gitgitclone git@example.com:group/project.git my-dir# 指定目录名日常最常用命令
查看状态与历史
gitstatus# 哪些文件改了、是否已暂存gitdiff# 工作区 vs 暂存区gitdiff--staged# 暂存区 vs 最后一次提交gitlog# 提交历史gitlog--oneline-10# 简洁一行,最近 10 条gitshow<commit># 某次提交的详情暂存与提交
gitaddfile.cpp# 暂存单个文件gitadd.# 暂存当前目录所有变更gitadd-pfile.cpp# 交互式分块暂存gitcommit-m"fix: 修复启动路径查找"gitcommit-am"docs: 更新说明"# -a:已跟踪文件的修改直接进提交(不含新文件)撤销与回退(谨慎使用)
# 丢弃工作区对某文件的修改(未 add)gitrestore file.cpp# 取消暂存(已 add,想重新选)gitrestore--stagedfile.cpp# 回退到某提交,保留工作区修改gitreset--soft<commit># 回退到某提交,暂存区和工作区也一起回退(未 push 时常用)gitreset--hard<commit># 用新提交“抵消”某次历史提交(已 push 时更安全)gitrevert<commit>reset --hard会丢失未提交修改,且若已 push 再改历史需要force push,团队协作时要避免。
分支
gitbranch# 列出本地分支gitbranch-a# 含远程跟踪分支gitbranch feature/foo# 新建分支gitswitch feature/foo# 切换分支(推荐)gitswitch-cfeature/foo# 新建并切换# 旧写法仍常见:gitcheckout feature/foogitcheckout-bfeature/foogitmerge develop# 把 develop 合并进当前分支gitbranch-dfeature/foo# 删除已合并分支远程协作(简要)
详细说明见上文本地仓库、远程仓库与分支。
gitremote-vgitfetch origingitpull# 已设上游时gitpull origin main# 未设上游时显式指定gitpush# 已设上游时gitpush-uorigin HEAD# 首次推送并设置跟踪暂存未完成的工作
gitstash# 把工作区改动收起来gitstash listgitstash pop# 恢复最近一次 stashgitstash apply# 恢复但保留 stash 记录比较与查找
gitdiffmain..feature/foo# 两分支差异gitdiffmain...feature/foo# 从共同祖先到 feature 的差异(看 PR 常用)gitblame file.cpp# 每行最后是谁改的gitgrep"FindStartup"# 在版本库中搜索字符串.gitignore
在项目根目录创建.gitignore,列出不要纳入版本控制的文件:
build/ *.o *.a .env .idea/已误跟踪的文件需先取消跟踪:
gitrm--cachedpath/to/file典型工作流
1. 拉最新代码再开发
gitswitch developgitpull origin developgitswitch-cfeature/my-change# ... 编辑 ...gitadd.gitcommit-m"feat: 添加 xxx"gitpush-uorigin feature/my-change然后在 Web 上提 Merge Request / Pull Request。
2. 同步远程 main 到当前分支
gitfetch origingitmerge origin/main# 或保持线性历史:gitrebase origin/main有冲突时 Git 会标记冲突文件,手工改完后:
gitadd<resolved-files>gitcommit# merge 场景# 或gitrebase--continue# rebase 场景3. 只看某次提交改了什么
gitshow HEADgitshow abc1234--stat配置(本机一次即可)
gitconfig--globaluser.name"Your Name"gitconfig--globaluser.email"you@example.com"gitconfig--globalcore.editor"vim"gitconfig--globalinit.defaultBranch main查看配置:
gitconfig--listgitconfig user.email命令速查表
| 目的 | 命令 |
|---|---|
| 克隆 | git clone <url> |
| 状态 | git status |
| 暂存 | git add <file> |
| 提交 | git commit -m "message" |
| 拉取 | git pull |
| 推送 | git push |
| 设上游跟踪 | git push -u origin <branch>或git branch --set-upstream-to=origin/<branch> |
| 看跟踪关系 | git branch -vv |
| 从远程建本地分支 | git switch -t origin/<branch> |
| 建分支 | git switch -c <branch> |
| 切分支 | git switch <branch> |
| 合并 | git merge <branch> |
| 看历史 | git log --oneline |
| 暂存工作 | git stash |
本人最常用
gitclonegitswitch-Cdevelop origin/developgitcheckout-bfeat/xxx/new_featgitadd.gitcommit-m"feat: 本次提交做了什么事"gitpush 上传到当前分支的远程跟踪分支gitpush origin feat/xxx/feat 上传到远程 feat/xxx/featgitpull 从当前分支的远程跟踪分支拉取代码gitpull origin feat/xxx/feat 从远程 feat/xxx/feat 分支拉取最新代码到当前本地分支gitstash 将工作区修改暂存在当前本地分支gitstash pop 将本地当前分支存储的修改取出到当前工作区gitreset--softHEAD~N N表示撤回最近的几次提交1次就改为1,--soft:仅撤销 commit,修改仍在「暂存区」gitreset HEAD~N 修改回到工作区(需重新gitadd)gitreset--hardHEAD~N 完全丢弃修改gitreset--hardcommit号 将当前分支强制回退到指定提交,同时丢弃工作区和暂存区所有修改。gitlog 查看当前本地分支的所有commit记录 删除gitbranch 查看本地分支列表gitbranch-Dxxx 删除本地分支xxxgitpush origin--deletefeat/xxx/new_feat 删除远程 feat/xxx/new_feat分支