Git 常用命令操作指南
目录
- 概述
- 核心概念
- 安装与配置
- 初始化或克隆仓库
- 日常开发流程
- 分支管理
- 查看历史与差异
- 撤销与回滚操作
- 临时保存工作现场
- 忽略无需跟踪的文件
- 典型工作流程示例
- 常用命令速查表
- 常见问题解答
- 总结
概述
Git 是一个开源的分布式版本控制系统,用于记录项目文件的每一次修改,方便多人协作、版本回退和追溯问题。
Git 的优势
- ✅分布式:每个开发者本地都拥有完整的项目仓库,可离线工作
- ✅高效:分支创建、切换、合并非常快速
- ✅强大:支持非线性开发,可以处理大型项目
- ✅安全:数据完整性保证,不易丢失
- ✅灵活:支持多种工作流程
核心概念
工作区 ↔ 暂存区 ↔ 本地仓库
Git 有三个主要区域:
┌─────────────────────────────────────┐ │ Git 工作流程 │ ├─────────────────────────────────────┤ │ 工作区 → 暂存区 → 本地仓库 │ │ (编辑) (准备) (保存) │ └─────────────────────────────────────┘1. 工作区 (Working Directory)
- 你正在编辑的文件目录
- 可以直接看到和修改的文件
2. 暂存区 (Stage/Index)
- 临时存放待提交的修改
- 通过
git add将工作区的改动添加到暂存区
3. 本地仓库 (Local Repository)
- 存放所有已提交的历史版本
- 通过
git commit将暂存区的内容提交到本地仓库
4. 远程仓库 (Remote Repository)
- 托管在 GitHub/Gitee/GitLab 等平台上的仓库
- 用于团队共享代码
- 通过
push和pull与本地同步
安装与配置
安装 Git
Windows:
- 访问 https://git-scm.com/downloads 下载并安装
- 或使用包管理器:
winget install Git.Git
macOS:
# 使用 Homebrewbrewinstallgit# 或使用 Xcode Command Line Toolsxcode-select --installLinux:
# Ubuntu/Debiansudoapt-getinstallgit# CentOS/RHELsudoyuminstallgit# Fedorasudodnfinstallgit配置用户信息
提交代码时会记录此信息,需要先配置:
全局配置(对所有项目生效):
gitconfig --global user.name"Your Name"gitconfig --global user.email"your.email@example.com"项目级配置(仅对当前项目生效):
gitconfig user.name"Your Name"gitconfig user.email"your.email@example.com"查看配置:
# 查看所有配置gitconfig --list# 查看全局配置gitconfig --global --list# 查看特定配置gitconfig user.namegitconfig user.email其他常用配置:
# 设置默认编辑器gitconfig --global core.editor"code --wait"# VS Codegitconfig --global core.editor"vim"# Vim# 设置默认分支名gitconfig --global init.defaultBranch main# 设置换行符处理(Windows)gitconfig --global core.autocrlftrue# 设置换行符处理(Linux/macOS)gitconfig --global core.autocrlf input# 设置别名(简化命令)gitconfig --global alias.st statusgitconfig --global alias.co checkoutgitconfig --global alias.br branchgitconfig --global alias.ci commit初始化或克隆仓库
新建项目
在项目根目录执行,会生成一个隐藏的.git目录:
gitinit初始化并指定默认分支:
gitinit -b main克隆现有项目
从远程地址(如 GitHub)复制整个项目到本地:
# HTTPS 方式gitclone https://github.com/用户名/仓库名.git# SSH 方式(需要配置 SSH 密钥)gitclone git@github.com:用户名/仓库名.git# 指定目录名gitclone https://github.com/用户名/仓库名.git my-project# 只克隆最新一次提交(浅克隆,节省空间)gitclone --depth1https://github.com/用户名/仓库名.git示例:
gitclone https://github.com/octocat/Hello-World.gitcdHello-World日常开发流程
1. 查看状态
检查哪些文件被修改或已暂存:
gitstatus状态说明:
Untracked files:未跟踪的文件(新文件)Changes not staged for commit:已修改但未暂存Changes to be committed:已暂存,准备提交
简洁输出:
gitstatus -s# 或gitstatus --short2. 暂存修改
将工作区的改动添加到暂存区,准备提交:
# 添加指定文件gitadd文件名# 添加指定目录gitadd目录名/# 添加当前目录所有改动(注意会包含未跟踪文件)gitadd.# 添加所有改动(包括删除的文件)gitadd-A# 或gitadd--all# 交互式添加(可以选择性地暂存部分改动)gitadd-p# 或gitadd--patch注意事项:
git add .会添加当前目录及子目录的所有改动- 使用前建议先用
git status查看有哪些改动 - 可以使用
.gitignore文件排除不需要跟踪的文件
3. 提交到本地仓库
将暂存区的内容创建一个版本记录:
# 基本提交gitcommit -m"这里写清晰的修改说明"# 提交并跳过暂存区(直接提交已跟踪文件的修改)gitcommit -am"修改说明"# 修改最后一次提交(如果忘记添加文件或修改提交信息)gitcommit --amend -m"新的提交信息"# 提交时查看改动gitcommit -v提交信息规范:
推荐使用约定式提交(Conventional Commits):
<type>(<scope>): <subject> <body> <footer>常用 type:
feat:新功能fix:修复 bugdocs:文档更新style:代码格式调整refactor:重构test:测试相关chore:构建/工具相关
示例:
gitcommit -m"feat(login): 实现用户登录功能"gitcommit -m"fix(api): 修复数据获取接口的bug"gitcommit -m"docs(readme): 更新项目说明文档"4. 推送到远程仓库
将本地提交同步到远程(如 GitHub):
# 首次推送(建立追踪关系)gitpush -u origin main# 后续推送gitpush# 推送到指定远程和分支gitpush origin main# 强制推送(谨慎使用)gitpush --force# 或gitpush -f推送所有分支:
gitpush --all origin推送标签:
gitpush origin --tags5. 拉取远程更新
在开始工作前,先获取并合并他人的最新代码,避免冲突:
# 拉取并合并gitpull origin main# 简写(如果已建立追踪关系)gitpull# 只拉取不合并gitfetch origin# 拉取后查看差异gitfetch origingitlog HEAD..origin/main推荐工作流程:
# 1. 开始工作前先拉取最新代码gitpull# 2. 进行开发...# 3. 提交改动gitadd.gitcommit -m"修改说明"# 4. 再次拉取(防止他人已推送新代码)gitpull# 5. 解决冲突(如果有)# 6. 推送到远程gitpush分支管理
分支是 Git 的核心功能,用于并行开发,如main(稳定版)、dev(开发版)、feature/login(功能分支)等。
查看分支
# 查看本地分支(* 号标记当前分支)gitbranch# 查看所有分支(含远程分支)gitbranch -a# 查看远程分支gitbranch -r# 查看分支及最后提交信息gitbranch -v创建与切换分支
# 创建新分支gitbranch dev# 切换到指定分支gitcheckout dev# 创建并立即切换到新分支(新版 Git 推荐)gitswitch -c feature/login# 或旧版写法gitcheckout -b feature/login# 基于指定提交创建分支gitbranch new-branch<commit-id># 基于远程分支创建本地分支gitcheckout -b local-branch origin/remote-branch新版 Git 推荐使用git switch:
# 切换分支gitswitch dev# 创建并切换gitswitch -c feature/login合并分支
通常在main分支上,将其他分支(如dev)的修改合并进来:
# 1. 切换到目标分支gitcheckout main# 2. 合并 dev 分支到当前分支gitmerge dev# 3. 解决冲突(如果有)# 4. 提交合并gitcommit合并选项:
# 普通合并(会创建合并提交)gitmerge dev# 快进合并(如果可能,不创建合并提交)gitmerge --ff dev# 禁止快进合并(总是创建合并提交)gitmerge --no-ff dev# 压缩合并(将分支的所有提交压缩成一个)gitmerge --squash dev处理合并冲突:
当合并出现冲突时:
- 查看冲突文件:
git status - 编辑冲突文件,解决冲突标记(
<<<<<<<,=======,>>>>>>>) - 标记为已解决:
git add 文件名 - 完成合并:
git commit
删除分支
# 删除已合并的分支gitbranch -d dev# 强制删除未合并的分支gitbranch -D dev# 删除远程分支gitpush origin --delete dev# 或gitpush origin :dev分支重命名
# 重命名当前分支gitbranch -m new-name# 重命名指定分支gitbranch -m old-name new-name查看历史与差异
查看提交历史
# 详细历史gitlog# 简洁单行历史gitlog --oneline# 图形化分支历史gitlog --graph# 显示所有分支gitlog --all --graph# 显示最近 n 次提交gitlog -n5# 显示指定文件的提交历史gitlog 文件名# 显示统计信息gitlog --stat# 显示补丁(具体改动)gitlog -p# 自定义格式gitlog --pretty=format:"%h - %an, %ar : %s"常用选项组合:
# 图形化单行历史gitlog --oneline --graph --all# 显示最近 10 次提交的统计gitlog --stat -10查看代码改动
# 查看工作区与暂存区的差异gitdiff# 查看暂存区与最新提交的差异gitdiff--staged# 或gitdiff--cached# 查看与上一次提交的差异gitdiffHEAD~1# 查看与指定提交的差异gitdiff<commit-id># 查看两个提交之间的差异gitdiff<commit1><commit2># 查看指定文件的差异gitdiff文件名# 查看统计信息gitdiff--stat查看特定提交的改动:
# 查看提交的详细信息gitshow<commit-id># 查看提交的统计信息gitshow --stat<commit-id># 查看提交的补丁gitshow -p<commit-id>撤销与回滚操作
撤销 git add
将文件从暂存区移回工作区:
# 旧版写法gitreset HEAD 文件名# 新版 Git 推荐写法gitrestore --staged 文件名# 撤销所有暂存的文件gitreset HEAD# 或gitrestore --staged.撤销工作区修改
将文件恢复到最近一次提交的状态(此操作不可逆,会丢失未提交的改动):
# 旧版写法gitcheckout -- 文件名# 新版 Git 推荐写法gitrestore 文件名# 撤销所有工作区修改gitrestore.# 撤销指定目录gitrestore 目录名/回滚提交(谨慎使用)
# 回滚到上一次提交,保留工作区和暂存区的修改gitreset --soft HEAD^# 回滚到上一次提交,清空暂存区,保留工作区的修改gitreset --mixed HEAD^# 或gitreset HEAD^# 彻底回滚到上一次提交,清空工作区和暂存区(危险操作)gitreset --hard HEAD^# 回滚到指定提交gitreset --hard<commit-id>reset 三种模式对比:
| 模式 | 工作区 | 暂存区 | 提交历史 | 说明 |
|---|---|---|---|---|
--soft | 保留 | 保留 | 回滚 | 最安全,只回滚提交历史 |
--mixed | 保留 | 清空 | 回滚 | 默认模式,回滚提交和暂存区 |
--hard | 清空 | 清空 | 回滚 | 最危险,完全回滚 |
安全撤销已推送的提交
创建一个新提交来抵消某个旧提交,不改变历史:
# 撤销指定提交gitrevert<commit-id># 撤销最近一次提交gitrevert HEAD# 撤销多个提交gitrevert HEAD~3..HEAD# 推送到远程gitpushrevert vs reset:
| 操作 | 适用场景 | 是否改变历史 | 是否安全 |
|---|---|---|---|
reset | 本地提交,未推送 | ✅ 改变 | ⚠️ 需谨慎 |
revert | 已推送的提交 | ❌ 不改变 | ✅ 安全 |
临时保存工作现场
当你正在一个分支上开发,但需要紧急切换到其他分支时,可以使用stash功能。
保存现场
# 保存当前工作现场gitstash push -m"描述信息"# 简写gitstash# 包含未跟踪的文件gitstash -u# 或gitstash --include-untracked# 包含被忽略的文件gitstash -a# 或gitstash --all恢复现场
# 恢复最近一次保存的现场,并从 stash 列表中删除gitstash pop# 恢复指定 stashgitstash pop stash@{0}# 恢复最近一次保存的现场,但保留在 stash 列表中gitstash apply# 恢复指定 stash,但保留在列表中gitstash apply stash@{0}查看和管理 stash 列表
# 查看 stash 列表gitstash list# 查看 stash 内容gitstash show stash@{0}# 查看 stash 详细内容gitstash show -p stash@{0}# 删除指定的 stashgitstash drop stash@{0}# 清空所有 stashgitstashclear忽略无需跟踪的文件
创建.gitignore文件,在其中列出你希望 Git 忽略的文件或目录。
.gitignore 文件示例
# 日志文件 *.log # 依赖目录 node_modules/ vendor/ # 构建输出 build/ dist/ *.o *.exe # 系统文件 .DS_Store Thumbs.db *.swp *.swo *~ # IDE 配置 .vscode/ .idea/ *.sublime-project *.sublime-workspace # 环境变量文件 .env .env.local .env.*.local # 临时文件 *.tmp *.temp .cache/ # 测试覆盖率 coverage/ .nyc_output/ # 操作系统文件 .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes.gitignore 规则
#开头的是注释*匹配任意字符(除了/)?匹配单个字符[abc]匹配括号内的任意字符**匹配任意目录层级!开头表示否定(不忽略)
示例:
# 忽略所有 .log 文件 *.log # 但不忽略 important.log !important.log # 忽略 build 目录下的所有文件 build/ # 忽略所有目录下的 build 文件夹 **/build/ # 忽略 .env 文件,但不忽略 .env.example .env !.env.example已跟踪文件的处理
如果文件已经被 Git 跟踪,需要先移除:
# 从 Git 中移除,但保留本地文件gitrm--cached 文件名# 从 Git 中移除目录gitrm-r --cached 目录名/# 然后添加到 .gitignoreecho"文件名">>.gitignoregitadd.gitignoregitcommit -m"chore: 添加 .gitignore 规则"典型工作流程示例
以下是一个从零开始,在 GitHub 上创建项目并开发的完整流程:
1. GitHub 创建仓库
登录 GitHub,新建一个仓库(如my-project),获取其 HTTPS 地址。
2. 本地克隆仓库
gitclone https://github.com/你的用户名/my-project.gitcdmy-project3. 创建功能分支
gitswitch -c feature/login4. 开发与提交
# ... 编写代码 ...# 添加改动gitadd.# 提交gitcommit -m"feat: 实现登录页面"5. 推送分支
gitpush -u origin feature/login6. 创建合并请求 (Pull Request)
在 GitHub 仓库页面,针对feature/login分支创建一个 PR,请求合并到main分支。
7. 代码审查与合并
团队成员在 PR 中讨论、审查代码,通过后由负责人将其合并到main分支。
8. 同步本地 main 分支
gitcheckout maingitpull origin main9. 删除功能分支
# 删除本地分支gitbranch -d feature/login# 删除远程分支(如果还没自动删除)gitpush origin --delete feature/login常用命令速查表
基础操作
| 命令 | 说明 |
|---|---|
git init | 初始化仓库 |
git clone <url> | 克隆远程仓库 |
git status | 查看状态 |
git add <file> | 添加到暂存区 |
git commit -m "msg" | 提交到本地仓库 |
git push | 推送到远程 |
git pull | 拉取远程更新 |
分支操作
| 命令 | 说明 |
|---|---|
git branch | 查看分支 |
git branch <name> | 创建分支 |
git switch <name> | 切换分支 |
git switch -c <name> | 创建并切换 |
git merge <branch> | 合并分支 |
git branch -d <name> | 删除分支 |
查看历史
| 命令 | 说明 |
|---|---|
git log | 查看提交历史 |
git log --oneline | 单行历史 |
git log --graph | 图形化历史 |
git diff | 查看差异 |
git show <commit> | 查看提交详情 |
撤销操作
| 命令 | 说明 |
|---|---|
git restore <file> | 撤销工作区修改 |
git restore --staged <file> | 撤销暂存 |
git reset --soft HEAD^ | 软回滚 |
git reset --hard HEAD^ | 硬回滚 |
git revert <commit> | 安全撤销 |
其他操作
| 命令 | 说明 |
|---|---|
git stash | 保存工作现场 |
git stash pop | 恢复工作现场 |
git tag <name> | 创建标签 |
git remote -v | 查看远程仓库 |
git config --list | 查看配置 |
常见问题解答
Q1: 如何查看远程仓库地址?
gitremote -vQ2: 如何添加远程仓库?
gitremoteaddorigin<url>Q3: 如何修改远程仓库地址?
gitremote set-url origin<new-url>Q4: 如何查看某个文件的修改历史?
gitlog --follow 文件名gitblame 文件名Q5: 如何比较两个分支的差异?
gitdiffbranch1..branch2gitdiffbranch1 branch2Q6: 如何查看某个提交修改了哪些文件?
gitshow --stat<commit-id>gitdiff-tree --no-commit-id --name-only -r<commit-id>Q7: 如何修改最后一次提交信息?
gitcommit --amend -m"新的提交信息"Q8: 如何查看配置信息?
gitconfig --listgitconfig user.namegitconfig user.emailQ9: 如何设置 Git 别名?
gitconfig --global alias.st statusgitconfig --global alias.co checkoutgitconfig --global alias.br branchgitconfig --global alias.ci commitQ10: 如何解决合并冲突?
- 查看冲突文件:
git status - 编辑冲突文件,解决冲突标记
- 标记为已解决:
git add 文件名 - 完成合并:
git commit
总结
核心工作流程
1. 拉取最新代码 (git pull) 2. 创建功能分支 (git switch -c feature/xxx) 3. 开发并提交 (git add, git commit) 4. 推送分支 (git push) 5. 创建 Pull Request 6. 代码审查与合并 7. 同步主分支 (git pull) 8. 删除功能分支 (git branch -d)最佳实践
- 提交前先拉取:
git pull避免冲突 - 频繁提交:小步快跑,便于回滚
- 清晰的提交信息:使用约定式提交格式
- 使用分支:功能开发使用独立分支
- 定期推送:及时同步到远程仓库
- 使用 .gitignore:忽略不需要跟踪的文件
- 谨慎使用 force push:避免覆盖他人代码
学习资源
- Git 官方文档
- Pro Git 中文版
- GitHub Guides
- Learn Git Branching