一、Git 基础概念
1.1 Git 简介
Git 是一个分布式版本控制系统,由 Linus Torvalds 于2005年创建,用于管理 Linux 内核开发。它旨在处理从小型到大型项目的快速和高效版本控制。
1.2 Git 的核心特点
- 分布式:这是 Git 与旧系统(如 SVN)最大的不同。
- 集中式(如 SVN):所有人的代码都保存在中央服务器。没有网络或服务器挂了,就无法提交。
- 分布式(Git):每个开发者的电脑上都有一个完整的仓库克隆,包含全部历史记录。你可以在本地提交、创建分支,等有网时再同步到远程服务器(如 GitHub、GitLab)。这更安全、更灵活。
- 速度快:绝大多数操作在本地完成,无需连接网络,因此极其迅速。
- 分支管理强大:分支是 Git 的“杀手级”功能。
- 可以瞬间创建一个新的分支(想象成一条平行时间线),在新分支上尝试新功能或修复 Bug,而不会影响主线(main 或 master 分支)。
- 完成后,可以轻松地将分支合并回主线。这种模式支撑了现代高效的工作流(如 Git Flow)。
- 保证完整性:Git 中所有数据在存储前都会计算一个唯一的“哈希值”(如 40位16进制数)。任何文件的细微改动都会导致哈希值巨变。这意味着历史记录不可被篡改,一旦提交,数据丢失的可能性极低。
1.3 Git 基础概念
- 仓库(Repository):仓库是 Git 存储项目文件和历史记录的地方。分为本地仓库和远程仓库。
- 工作区(Working Directory):本地目录,包含项目的实际文件。
- 暂存区(Staging Area / Index):一个中间区域,用于准备提交。只有添加到暂存区的更改才会被包含在下次提交中。
- 提交(Commit):提交是项目在某个时间点的快照。每个提交都有一个唯一的 SHA-1 哈希标识。
- 分支(Branch):分支是开发线,允许并行开发。默认分支通常是 master 或 main。
- 标签(Tag):标签是特定提交的静态引用,常用于版本发布。
- 远程(Remote):远程仓库是托管在服务器上的仓库,用于团队协作。
1.4 Git 工作流程
Git 的整个工作流程主要分布在四个区域,其流程只要有以下几步:
- 从中央仓库克隆代码到本地工作区。
- 在本地工作区进行修改的文件,会临时存放在暂存区 。
- 通过
git commit命令将暂存区存放的改动过的文件提交到本地仓库中。 - 最后再通过
git push命令将本地仓库中的改动文件推送到远程仓库中。
工作区(Working Directory)↓ 修改文件 暂存区(Staging Area)↓gitcommit 本地仓库(Local Repository)↓gitpush 远程仓库(Remote Repository)对应的基本流程和命令:
# 1. 初始化仓库或克隆远程仓库gitinit# 在当前文件夹新建一个Git仓库gitclone<远程仓库地址># 下载一个远程仓库到本地# 2. 查看状态gitstatus# 查看哪些文件被修改、哪些已暂存# 3. 添加改动到暂存区gitadd<文件名># 添加某个特定文件gitadd.# 添加所有改动过的文件# 4. 提交到本地仓库gitcommit -m"提交的描述信息"# 提交暂存区的内容,并附上说明# 5. 同步远程仓库gitpush# 将本地提交推送到远程服务器gitpull# 从远程服务器拉取最新更新并合并到本地gitfetch# 仅从远程获取最新信息,但不自动合并# 6. 分支操作gitbranch# 查看所有分支gitbranch<分支名># 创建新分支gitcheckout<分支名># 切换到某个分支 (旧命令)gitswitch<分支名># 切换到某个分支 (新推荐命令)gitmerge<分支名># 将指定分支合并到当前分支# 7. 查看历史gitlog# 查看提交历史gitlog --oneline --graph# 以简洁图形化方式查看历史二、Git 基本配置
2.1 基础配置
# 1. 用户身份配置(必须)gitconfig --global user.name"你的名字"gitconfig --global user.email"你的邮箱@example.com"# 2. 编辑器配置gitconfig --global core.editor"code --wait"# VS Codegitconfig --global core.editor"vim"# Vim# 3. 行尾符配置(跨平台协作重要!)gitconfig --global core.autocrlftrue# Windowsgitconfig --global core.autocrlf input# Linux/Mac# 4. 别名配置(提高效率)gitconfig --global alias.co checkoutgitconfig --global alias.br branchgitconfig --global alias.ci commitgitconfig --global alias.st statusgitconfig --global alias.unstage'reset HEAD --'gitconfig --global alias.last'log -1 HEAD'gitconfig --global alias.lg"log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"# 5. 查看所有配置gitconfig --list --show-origin# 6. 配置文件位置# 系统级: /etc/gitconfig# 用户级: ~/.gitconfig 或 ~/.config/git/config# 仓库级: .git/config2.2 SSH 密钥配置(GitHub/GitLab)
# 1. 生成 SSH 密钥ssh-keygen -t ed25519 -C"your_email@example.com"# 或使用 RSA:ssh-keygen -t rsa -b 4096 -C "your_email@example.com"# 2. 启动 SSH 代理eval"$(ssh-agent -s)"# 3. 添加私钥到代理ssh-add ~/.ssh/id_ed25519# 4. 复制公钥cat~/.ssh/id_ed25519.pub# 5. 添加到 GitHub/GitLab# GitHub: Settings → SSH and GPG keys → New SSH key# GitLab: Preferences → SSH Keys# 6. 测试连接ssh-T git@github.comssh-T git@gitlab.com三、Git 核心操作详解
3.1 仓库创建与克隆
# 创建新仓库mkdirmy-projectcdmy-projectgitinit# 初始化仓库gitinit --bare# 创建裸仓库(服务器用)# 克隆现有仓库gitclone<repository-url># 克隆到当前目录gitclone<url>my-project# 克隆到指定目录gitclone --depth1<url># 浅克隆(只克隆最新提交)gitclone --branch develop<url># 克隆指定分支gitclone --recursive<url># 递归克隆子模块# 查看远程仓库gitremote -v# 查看远程仓库地址gitremote show origin# 查看远程仓库详细信息3.2 文件状态与基础操作
# 检查状态gitstatus# 详细状态gitstatus -s# 简洁状态gitstatus --ignored# 显示被忽略的文件# 添加文件到暂存区gitaddREADME.md# 添加单个文件gitaddsrc/# 添加目录gitadd.# 添加所有文件gitadd-A# 添加所有文件(包括删除的)gitadd-u# 添加已跟踪文件gitadd-p# 交互式添加(选择部分修改)# 提交更改gitcommit -m"提交信息"# 简单提交gitcommit -m"标题"-m"详细描述"# 多行提交信息gitcommit -a -m"信息"# 跳过暂存,提交所有已跟踪文件gitcommit --amend# 修改上次提交(可改信息或添加文件)gitcommit --allow-empty# 允许空提交# 查看提交历史gitlog# 详细日志gitlog --oneline# 单行显示gitlog --graph# 图形化显示分支gitlog --stat# 显示文件变更统计gitlog -p# 显示具体修改内容gitlog --since="2023-01-01"# 按时间筛选gitlog --author="名字"# 按作者筛选gitlog --grep="关键词"# 按提交信息筛选gitlog -S"functionName"# 搜索代码变更gitlog --follow<file># 跟踪文件历史(包括重命名)# 比较差异gitdiff# 工作区与暂存区差异gitdiff--staged# 暂存区与上次提交差异gitdiffHEAD# 工作区与最新提交差异gitdiff<commit1><commit2># 两个提交间的差异gitdiff--cached# 同 --stagedgitdiff--word-diff# 单词级差异显示gitdiff--color-words# 彩色单词差异3.3 分支管理
# 查看分支gitbranch# 查看本地分支gitbranch -r# 查看远程分支gitbranch -a# 查看所有分支gitbranch -v# 查看分支最后提交gitbranch --merged# 查看已合并的分支gitbranch --no-merged# 查看未合并的分支# 创建分支gitbranch feature-branch# 创建分支gitbranch -m old-name new-name# 重命名分支gitbranch -d branch-name# 删除已合并分支gitbranch -D branch-name# 强制删除分支# 切换分支gitcheckout develop# 切换到已有分支gitcheckout -b feature-branch# 创建并切换到新分支gitcheckout --track origin/develop# 跟踪远程分支gitswitch develop# Git 2.23+ 推荐方式gitswitch -c feature-branch# 创建并切换(推荐)# 合并分支gitmerge feature-branch# 合并到当前分支gitmerge --no-ff feature-branch# 禁用 fast-forward,保留合并记录gitmerge --squash feature-branch# 压缩合并为单个提交gitmerge --abort# 中止合并(有冲突时)# 变基(Rebase)gitrebase develop# 将当前分支变基到developgitrebase -i HEAD~3# 交互式变基(最近3个提交)gitrebase --continue# 继续变基(解决冲突后)gitrebase --abort# 中止变基gitrebase --skip# 跳过当前提交# 标签管理gittag v1.0.0# 创建轻量标签gittag -a v1.0.0 -m"版本1.0.0"# 创建附注标签gittag -d v1.0.0# 删除标签gitpush origin v1.0.0# 推送标签到远程gitpush origin --tags# 推送所有标签gitpush origin :refs/tags/v1.0.0# 删除远程标签gitcheckout v1.0.0# 切换到标签gitshow v1.0.0# 查看标签信息3.4 远程仓库操作
# 添加远程仓库gitremoteaddorigin<url># 添加远程仓库gitremote set-url origin<new-url># 修改远程仓库地址gitremote remove origin# 删除远程仓库# 拉取代码gitpull# 拉取并合并(相当于 fetch + merge)gitpull origin develop# 拉取指定分支gitpull --rebase# 拉取并使用 rebasegitfetch# 仅获取,不合并gitfetch --prune# 获取并清理已删除的远程分支gitfetch --all# 获取所有远程仓库# 推送代码gitpush# 推送到默认分支gitpush origin develop# 推送到指定分支gitpush -u origin develop# 推送并设置 upstreamgitpush --force# 强制推送(谨慎使用!)gitpush --force-with-lease# 安全强制推送(推荐)gitpush --delete origin branch-name# 删除远程分支gitpush origin --tags# 推送所有标签# 跟踪分支gitbranch -u origin/develop# 设置当前分支跟踪远程分支gitbranch -vv# 查看跟踪关系四、高级操作与技巧
4.1 撤销与重置
# 撤销工作区的修改gitcheckout -- file.txt# 丢弃工作区修改gitcheckout.# 丢弃所有修改gitclean -fd# 删除未跟踪的文件和目录gitclean -n# 预览将要删除的文件# 撤销暂存区的修改gitreset HEAD file.txt# 从暂存区移除文件gitreset.# 从暂存区移除所有文件# 撤销提交gitreset --soft HEAD~1# 撤销提交,保留修改到暂存区gitreset --mixed HEAD~1# 撤销提交,保留修改到工作区(默认)gitreset --hard HEAD~1# 彻底丢弃提交和修改(危险!)gitrevert<commit-hash># 创建新的提交来撤销之前的提交(安全)# 恢复删除的文件gitcheckout HEAD -- file.txt# 恢复已删除的文件gitcheckout<commit>-- file.txt# 从特定提交恢复文件4.2 暂存和恢复
# 暂存当前工作(临时保存修改)gitstash# 暂存所有修改gitstash save"message"# 暂存并添加描述gitstash -u# 暂存包括未跟踪的文件gitstash -a# 暂存所有文件(包括忽略的文件)# 查看和应用暂存gitstash list# 查看所有暂存gitstash show stash@{0}# 查看某个暂存的内容gitstash apply stash@{0}# 应用某个暂存(不删除)gitstash pop# 应用最新暂存并删除gitstash drop stash@{0}# 删除某个暂存gitstashclear# 清除所有暂存4.3 子模块
# 添加子模块gitsubmoduleadd<repository-url>path/to/submodulegitsubmoduleadd--name custom-name<url><path># 克隆包含子模块的项目gitclone<repository-url>gitsubmodule init# 初始化子模块gitsubmodule update# 更新子模块# 或一步完成:git clone --recursive <url># 子模块操作gitsubmodule update --remote# 更新子模块到最新提交gitsubmodule foreach'git pull origin main'# 批量操作子模块gitsubmodule deinit path/to/submodule# 反初始化子模块gitsubmodulesync# 同步子模块URL# 子模块更新提交cdsubmodule-directorygitcheckout maingitpullcd..gitaddsubmodule-directorygitcommit -m"更新子模块"4.4 钩子
# 客户端钩子位置:.git/hooks/# 常用钩子:# pre-commit 提交前执行(代码检查)# prepare-commit-msg 准备提交信息时# commit-msg 提交信息保存后# post-commit 提交完成后# pre-push 推送前执行# 示例:pre-commit 钩子#!/bin/sh# .git/hooks/pre-commitecho"Running pre-commit checks..."# 运行代码检查npmrun lintif[$?-ne0];thenecho"Lint检查失败!"exit1fi# 运行测试npmtestif[$?-ne0];thenecho"测试失败!"exit1fiecho"所有检查通过!"# 使钩子可执行chmod+x .git/hooks/pre-commit# 使用预提交框架(推荐)# https://pre-commit.com/pipinstallpre-commit pre-commitinstall五、实用工作流示例
5.1 日常开发流程
# 1. 开始新功能开发gitswitch main# 切换到主分支gitpull origin main# 获取最新代码gitswitch -c feature/new-login# 创建并切换到新功能分支# 2. 日常开发gitadd.# 添加修改gitcommit -m"实现登录功能"# 提交修改# ... 重复多次# 3. 完成功能,准备合并gitswitch main# 切换到主分支gitpull origin main# 再次更新gitswitch feature/new-login# 回到功能分支gitrebase main# 变基到主分支(保持历史线性)# 或使用 mergegitmerge main# 合并主分支到功能分支# 4. 推送到远程并创建PRgitpush -u origin feature/new-login# 然后在GitHub/GitLab上创建Pull Request5.2 修复线上Bug
# 1. 基于主分支创建热修复分支gitswitch maingitpull origin maingitswitch -c hotfix/critical-bug# 2. 修复并提交# ... 修复代码 ...gitadd.gitcommit -m"修复XX问题"# 3. 测试后合并gitswitch maingitmerge --no-ff hotfix/critical-buggittag -a v1.0.1 -m"修复版本1.0.1"gitpush origin main --tags# 4. 同步到开发分支gitswitch developgitmerge main5.3 清理本地分支
# 删除已合并的本地分支gitbranch --merged|grep-v"\*"|grep-v"main"|xargs-n1gitbranch -d# 删除远程已删除分支的本地引用gitfetch --prune5.4 最佳实践建议
- 提交规范
- 使用有意义的提交信息
- 遵循约定式提交(Conventional Commits)
- 单次提交只做一件事
- 分支策略
- main/master:生产代码
- develop:开发主分支
- feature/*:功能开发分支
- hotfix/*:紧急修复分支
- release/*:发布分支
- 工作习惯
- 频繁提交,小步快跑
- 提交前先拉取最新代码
- 使用Pull Request进行代码审查
- 定期清理无用分支
- 安全注意
- 慎用 git push --force
- 重要分支设置保护规则
- 备份重要分支的提交哈希值
六、Git 配置优化
6.1 .gitconfig 配置文件示例
[user]name=Your Name email=your.email@example.com[core]editor=code --wait autocrlf=input# Mac/Linux# autocrlf = true # Windows[alias]co=checkout ci=commit st=status br=branch hist=log --pretty=format:'%h %ad | %s%d [%an]'--graph --date=shorttype=cat-file -t dump=cat-file -p[pull]rebase=false# 设置pull的默认行为[push]default=simple[color]ui=auto6.2 .gitignore 文件示例
# 系统文件.DS_Store Thumbs.db# 依赖目录node_modules/ vendor/ dist/ build/# 环境文件.env .env.local .env.production# 编辑器.vscode/ .idea/ *.swp *.swo# 日志*.log npm-debug.log*# 系统特定*.exe *.dll *.so *.dylib