Git 是现代软件开发中不可或缺的分布式版本控制系统,它不仅能够追踪代码变更历史,还能支持复杂的团队协作和分支管理。本指南将从基础概念开始,逐步深入到高级技巧,帮助您全面掌握 Git 的使用。
Git 基础概念#
什么是 Git#
Git 是由 Linux 之父 Linus Torvalds 创建的分布式版本控制系统,具有以下特点:
- 分布式架构: 每个开发者都拥有完整的代码历史
- 高性能: 快速的分支创建和合并
- 数据完整性: 通过 SHA-1 哈希确保数据完整性
- 灵活的工作流: 支持多种开发模式
核心概念#
工作区域#
Git 中有三个主要的工作区域:
flowchart LR
subgraph WorkingDir[工作目录 Working Dir]
A[修改文件]
end
subgraph Staging[暂存区 Staging Area]
B[暂存文件]
end
subgraph Repository[版本库 Repository]
C[提交记录]
end
A -->|"git add"| B
B -->|"git commit"| C
C -->|"git push"| D[远程仓库]
文件状态#
Git 中的文件有四种状态:
- Untracked: 未跟踪的新文件
- Modified: 已修改但未暂存
- Staged: 已暂存待提交
- Committed: 已提交到版本库
环境配置#
初始配置#
# 设置用户信息
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# 设置默认编辑器
git config --global core.editor vim
# 设置默认分支名称
git config --global init.defaultBranch main
# 启用颜色输出
git config --global color.ui auto
# 设置换行符处理(Windows 用户)
git config --global core.autocrlf true
# 设置换行符处理(Linux/Mac 用户)
git config --global core.autocrlf input
配置级别#
Git 配置有三个级别:
# 系统级配置(影响所有用户)
git config --system
# 用户级配置(影响当前用户)
git config --global
# 仓库级配置(仅影响当前仓库)
git config --local
查看配置#
# 查看所有配置
git config --list
# 查看特定配置
git config user.name
git config user.email
# 查看配置来源
git config --list --show-origin
仓库初始化和管理#
创建新仓库#
本地初始化#
# 在当前目录初始化 Git 仓库
git init
# 在指定目录初始化仓库
git init project-name
# 初始化裸仓库(用于服务器)
git init --bare
克隆远程仓库#
# 克隆仓库到当前目录
git clone https://github.com/user/repo.git
# 克隆到指定目录
git clone https://github.com/user/repo.git my-project
# 克隆指定分支
git clone -b develop https://github.com/user/repo.git
# 浅克隆(只获取最近的提交历史)
git clone --depth 1 https://github.com/user/repo.git
# 克隆时指定远程名称
git clone -o upstream https://github.com/user/repo.git
远程仓库管理#
添加和管理远程仓库#
# 查看远程仓库
git remote -v
# 添加远程仓库
git remote add origin https://github.com/user/repo.git
# 添加多个远程仓库
git remote add upstream https://github.com/original/repo.git
git remote add fork https://github.com/yourfork/repo.git
# 重命名远程仓库
git remote rename origin old-origin
# 删除远程仓库
git remote remove origin
# 查看远程仓库详细信息
git remote show origin
更改远程仓库地址#
# 查看当前远程仓库地址
git remote -v
# 更新远程仓库地址
git remote set-url origin https://github.com/user/new-repo.git
# 为推送和拉取设置不同的 URL
git remote set-url origin https://github.com/user/repo.git
git remote set-url --push origin https://github.com/user/repo.git
# 添加额外的推送 URL(同时推送到多个仓库)
git remote set-url --add --push origin https://github.com/user/repo.git
git remote set-url --add --push origin https://gitlab.com/user/repo.git
连接本地仓库到远程仓库#
场景一:本地项目推送到新的远程仓库#
# 1. 初始化本地仓库(如果还没有)
git init
# 2. 添加文件到暂存区
git add .
# 3. 创建初始提交
git commit -m "Initial commit"
# 4. 添加远程仓库
git remote add origin https://github.com/user/repo.git
# 5. 推送到远程仓库
git push -u origin main
场景二:连接到已有内容的远程仓库#
# 1. 添加远程仓库
git remote add origin https://github.com/user/repo.git
# 2. 拉取远程代码(允许不相关历史)
git pull origin main --allow-unrelated-histories
# 3. 解决可能的冲突
git add .
git commit -m "Merge remote repository"
# 4. 设置跟踪分支
git branch --set-upstream-to=origin/main main
# 5. 后续正常操作
git push
场景三:Fork 工作流设置#
# 1. 克隆你的 fork
git clone https://github.com/yourusername/repo.git
cd repo
# 2. 添加上游仓库
git remote add upstream https://github.com/original/repo.git
# 3. 验证远程仓库设置
git remote -v
# origin https://github.com/yourusername/repo.git (fetch)
# origin https://github.com/yourusername/repo.git (push)
# upstream https://github.com/original/repo.git (fetch)
# upstream https://github.com/original/repo.git (push)
# 4. 同步上游更新
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
仓库状态检查#
# 查看仓库状态
git status
# 简洁状态显示
git status -s
# 查看忽略的文件
git status --ignored
# 查看分支状态
git status -b
# 查看工作目录和暂存区的差异
git diff
# 查看暂存区和最后一次提交的差异
git diff --staged
# 查看工作目录和最后一次提交的差异
git diff HEAD
分支管理#
分支是 Git 最强大的功能之一,它允许您并行开发不同的功能,而不会相互干扰。
分支基础操作#
创建和切换分支#
# 查看所有分支
git branch
# 查看所有分支(包括远程分支)
git branch -a
# 查看远程分支
git branch -r
# 创建新分支
git branch feature-login
# 创建并切换到新分支
git checkout -b feature-login
# 使用新语法创建并切换分支
git switch -c feature-login
# 从指定提交创建分支
git checkout -b hotfix-123 abc1234
# 从远程分支创建本地分支
git checkout -b local-branch origin/remote-branch
分支切换#
# 切换分支
git checkout main
git switch main # 新语法
# 切换到上一个分支
git checkout -
git switch -
# 强制切换(丢弃当前更改)
git checkout -f main
分支重命名和删除#
# 重命名当前分支
git branch -m new-branch-name
# 重命名指定分支
git branch -m old-name new-name
# 删除本地分支
git branch -d feature-login
# 强制删除本地分支(即使未合并)
git branch -D feature-login
# 删除远程分支
git push origin --delete feature-login
# 清理已删除的远程分支引用
git remote prune origin
分支合并#
快进合并(Fast-forward)#
# 切换到目标分支
git checkout main
# 执行快进合并
git merge feature-login
# 禁用快进合并(创建合并提交)
git merge --no-ff feature-login
三方合并(Three-way merge)#
# 当分支有分叉时,Git 会自动进行三方合并
git checkout main
git merge feature-login
# 如果有冲突,需要手动解决
# 1. 编辑冲突文件
# 2. 标记为已解决
git add conflicted-file.txt
# 3. 完成合并
git commit
压缩合并(Squash merge)#
# 将分支的所有提交压缩为一个提交
git checkout main
git merge --squash feature-login
git commit -m "Add login feature"
变基操作(Rebase)#
变基是另一种整合分支的方法,它可以创建更线性的提交历史。
基础变基#
# 将当前分支变基到 main
git checkout feature-login
git rebase main
# 或者一步完成
git rebase main feature-login
交互式变基#
# 交互式变基最近 3 个提交
git rebase -i HEAD~3
# 交互式变基到指定提交
git rebase -i abc1234
在交互式变基中,您可以:
pick: 保留提交reword: 修改提交信息edit: 修改提交内容squash: 合并到前一个提交drop: 删除提交
解决变基冲突#
# 当变基遇到冲突时
# 1. 解决冲突文件
# 2. 添加解决后的文件
git add .
# 3. 继续变基
git rebase --continue
# 跳过当前提交
git rebase --skip
# 中止变基操作
git rebase --abort
分支工作流#
Git Flow 工作流#
# 主要分支
# - main: 生产分支
# - develop: 开发分支
# 创建开发分支
git checkout -b develop main
# 创建功能分支
git checkout -b feature/user-auth develop
# 完成功能开发后合并到 develop
git checkout develop
git merge --no-ff feature/user-auth
git branch -d feature/user-auth
# 创建发布分支
git checkout -b release/1.0.0 develop
# 发布完成后合并到 main 和 develop
git checkout main
git merge --no-ff release/1.0.0
git tag -a v1.0.0 -m "Release version 1.0.0"
git checkout develop
git merge --no-ff release/1.0.0
git branch -d release/1.0.0
GitHub Flow 工作流#
# 1. 从 main 创建功能分支
git checkout main
git pull origin main
git checkout -b feature/new-feature
# 2. 开发并提交
git add .
git commit -m "Add new feature"
# 3. 推送分支
git push origin feature/new-feature
# 4. 创建 Pull Request
# 5. 代码审查和讨论
# 6. 合并到 main
# 7. 删除功能分支
git checkout main
git pull origin main
git branch -d feature/new-feature
认证和凭据管理#
SSH 密钥认证(推荐)#
SSH 密钥认证是最安全和便捷的认证方式:
生成 SSH 密钥#
# 生成新的 SSH 密钥对
ssh-keygen -t ed25519 -C "your.email@example.com"
# 如果系统不支持 ed25519,使用 RSA
ssh-keygen -t rsa -b 4096 -C "your.email@example.com"
# 指定密钥文件名
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_github -C "your.email@example.com"
添加 SSH 密钥到 ssh-agent#
# 启动 ssh-agent
eval "$(ssh-agent -s)"
# 添加私钥到 ssh-agent
ssh-add ~/.ssh/id_ed25519
# 查看已添加的密钥
ssh-add -l
配置 SSH 客户端#
# 创建或编辑 SSH 配置文件
vim ~/.ssh/config
# 添加以下内容
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab
IdentitiesOnly yes
测试 SSH 连接#
# 测试 GitHub 连接
ssh -T git@github.com
# 测试 GitLab 连接
ssh -T git@gitlab.com
HTTPS 认证管理#
凭据助手配置#
# Windows 系统
git config --global credential.helper manager-core
# macOS 系统
git config --global credential.helper osxkeychain
# Linux 系统
git config --global credential.helper store
# 临时缓存凭据(15分钟)
git config --global credential.helper 'cache --timeout=900'
清理存储的凭据#
# Windows 系统:清理凭据管理器
git config --global --unset credential.helper
cmdkey /delete:git:https://github.com
# macOS 系统:清理钥匙串
git config --global --unset credential.helper
security delete-internet-password -s github.com
# Linux 系统:删除凭据文件
rm ~/.git-credentials
# 清理缓存的凭据
git credential-cache exit
个人访问令牌(PAT)#
对于 GitHub、GitLab 等平台,推荐使用个人访问令牌:
# 使用令牌作为密码
# 用户名:你的用户名
# 密码:生成的个人访问令牌
# 在 URL 中包含令牌(不推荐,会暴露在历史记录中)
git clone https://username:token@github.com/user/repo.git
# 推荐方式:配置凭据助手,首次输入后会自动保存
git clone https://github.com/user/repo.git
# 输入用户名和令牌
多账户管理#
使用不同的 SSH 密钥#
# 为不同账户生成不同的密钥
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C "work@company.com"
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_personal -C "personal@gmail.com"
# 配置 SSH config
cat >> ~/.ssh/config << 'EOF'
# 工作账户
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
# 个人账户
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
EOF
# 克隆时使用不同的 Host
git clone git@github-work:company/repo.git
git clone git@github-personal:username/repo.git
为不同项目配置不同用户信息#
# 进入工作项目目录
cd work-project
git config user.name "Work Name"
git config user.email "work@company.com"
# 进入个人项目目录
cd personal-project
git config user.name "Personal Name"
git config user.email "personal@gmail.com"
# 或者使用条件配置
cat >> ~/.gitconfig << 'EOF'
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:~/personal/"]
path = ~/.gitconfig-personal
EOF
# 创建工作配置文件
cat > ~/.gitconfig-work << 'EOF'
[user]
name = Work Name
email = work@company.com
EOF
# 创建个人配置文件
cat > ~/.gitconfig-personal << 'EOF'
[user]
name = Personal Name
email = personal@gmail.com
EOF
提交管理#
基本提交操作#
添加文件到暂存区#
# 添加指定文件
git add file1.txt file2.txt
# 添加所有修改的文件
git add .
# 添加所有文件(包括删除的文件)
git add -A
# 交互式添加
git add -i
# 分块添加(部分添加文件的某些更改)
git add -p
创建提交#
# 基本提交
git commit -m "Add new feature"
# 多行提交信息
git commit -m "Add user authentication
- Implement login functionality
- Add password validation
- Create user session management"
# 修改最后一次提交
git commit --amend -m "Updated commit message"
# 添加文件到最后一次提交
git add forgotten-file.txt
git commit --amend --no-edit
# 空提交(用于触发 CI/CD)
git commit --allow-empty -m "Trigger CI build"
提交信息规范#
推荐使用约定式提交(Conventional Commits)格式:
# 格式:<type>(<scope>): <description>
git commit -m "feat(auth): add user login functionality"
git commit -m "fix(api): resolve null pointer exception"
git commit -m "docs(readme): update installation instructions"
git commit -m "style(css): fix button alignment"
git commit -m "refactor(utils): extract common functions"
git commit -m "test(auth): add unit tests for login"
git commit -m "chore(deps): update dependencies"
查看提交历史#
基本日志查看#
# 查看提交历史
git log
# 简洁的一行显示
git log --oneline
# 显示图形化分支结构
git log --graph --oneline --all
# 显示统计信息
git log --stat
# 显示详细的文件变更
git log -p
# 限制显示数量
git log -n 5
# 按时间范围查看
git log --since="2023-01-01" --until="2023-12-31"
git log --since="2 weeks ago"
高级日志查看#
# 按作者过滤
git log --author="John Doe"
# 按提交信息过滤
git log --grep="fix"
# 按文件过滤
git log -- path/to/file.txt
# 查看某个文件的修改历史
git log -p -- file.txt
# 查看删除的文件
git log --diff-filter=D --summary
# 自定义格式
git log --pretty=format:"%h - %an, %ar : %s"
# 查看分支间的差异
git log main..feature-branch
git log feature-branch --not main
修改提交历史#
修改最后一次提交#
# 修改提交信息
git commit --amend -m "New commit message"
# 添加文件到最后一次提交
git add forgotten-file.txt
git commit --amend --no-edit
# 修改作者信息
git commit --amend --author="New Author <new@email.com>"
交互式变基修改历史#
# 修改最近 3 次提交
git rebase -i HEAD~3
# 修改到指定提交
git rebase -i abc1234
在交互式变基编辑器中:
pick或p: 保留提交reword或r: 修改提交信息edit或e: 修改提交内容squash或s: 合并到前一个提交fixup或f: 合并到前一个提交但丢弃提交信息drop或d: 删除提交
拆分提交#
# 1. 开始交互式变基
git rebase -i HEAD~3
# 2. 将要拆分的提交标记为 'edit'
# 3. 重置到前一个提交
git reset HEAD^
# 4. 分别添加和提交文件
git add file1.txt
git commit -m "First part of the change"
git add file2.txt
git commit -m "Second part of the change"
# 5. 继续变基
git rebase --continue
合并提交#
# 使用 squash 合并最近 3 个提交
git rebase -i HEAD~3
# 将后面的提交改为 'squash' 或 's'
# 或者使用 reset 和重新提交
git reset --soft HEAD~3
git commit -m "Combined commit message"
撤销和恢复#
撤销工作目录的更改#
# 撤销单个文件的更改
git checkout -- file.txt
git restore file.txt # 新语法
# 撤销所有文件的更改
git checkout -- .
git restore .
# 撤销到指定提交的状态
git checkout abc1234 -- file.txt
撤销暂存区的更改#
# 取消暂存单个文件
git reset HEAD file.txt
git restore --staged file.txt # 新语法
# 取消暂存所有文件
git reset HEAD
git restore --staged .
撤销提交#
# 软重置:保留工作目录和暂存区的更改
git reset --soft HEAD~1
# 混合重置:保留工作目录的更改,清空暂存区
git reset --mixed HEAD~1
git reset HEAD~1 # 默认是 mixed
# 硬重置:丢弃所有更改
git reset --hard HEAD~1
# 重置到指定提交
git reset --hard abc1234
使用 revert 安全撤销#
# 创建一个新提交来撤销指定提交
git revert abc1234
# 撤销合并提交
git revert -m 1 merge-commit-hash
# 撤销多个提交
git revert HEAD~3..HEAD
历史记录管理#
查找和恢复#
查找丢失的提交#
# 查看引用日志(包括已删除的提交)
git reflog
# 查看所有分支的引用日志
git reflog --all
# 恢复丢失的提交
git checkout abc1234
git branch recovered-branch abc1234
# 查找包含特定内容的提交
git log -S "search_string" --source --all
# 查找特定文件的历史
git log --follow -- path/to/file.txt
使用 git fsck 检查仓库#
# 检查仓库完整性
git fsck
# 查找悬空的对象
git fsck --unreachable
# 查找悬空的提交
git fsck --lost-found
文件操作#
文件状态管理#
忽略文件#
# 创建 .gitignore 文件
cat > .gitignore << 'EOF'
# 编译输出
*.o
*.so
*.exe
build/
dist/
# 依赖目录
node_modules/
vendor/
# 日志文件
*.log
logs/
# 配置文件
.env
config.local.json
# IDE 文件
.vscode/
.idea/
*.swp
*.swo
# 操作系统文件
.DS_Store
Thumbs.db
EOF
# 忽略已跟踪的文件
git rm --cached file.txt
echo "file.txt" >> .gitignore
git add .gitignore
git commit -m "Ignore file.txt"
文件重命名和移动#
# 重命名文件
git mv old-name.txt new-name.txt
# 移动文件
git mv file.txt directory/
# 移动并重命名
git mv old-file.txt new-directory/new-file.txt
# 如果已经在文件系统中移动了文件
git add new-location/file.txt
git rm old-location/file.txt
删除文件#
# 删除文件并从版本控制中移除
git rm file.txt
# 只从版本控制中移除,保留本地文件
git rm --cached file.txt
# 强制删除(即使文件已修改)
git rm -f file.txt
# 删除目录
git rm -r directory/
文件差异和比较#
查看差异#
# 工作目录 vs 暂存区
git diff
# 暂存区 vs 最后一次提交
git diff --staged
git diff --cached
# 工作目录 vs 最后一次提交
git diff HEAD
# 比较两个提交
git diff commit1 commit2
# 比较两个分支
git diff main feature-branch
# 只显示文件名
git diff --name-only
# 显示统计信息
git diff --stat
高级差异查看#
# 按单词显示差异
git diff --word-diff
# 忽略空白字符
git diff --ignore-space-change
git diff --ignore-all-space
# 比较特定文件
git diff HEAD -- file.txt
# 使用外部工具查看差异
git difftool
git difftool --tool=vimdiff
暂存(Stash)操作#
暂存功能允许您临时保存工作进度,切换分支处理其他任务。
基本暂存操作#
# 暂存当前更改
git stash
# 暂存时添加描述
git stash push -m "Work in progress on feature X"
# 暂存包括未跟踪的文件
git stash -u
# 暂存包括忽略的文件
git stash -a
# 查看暂存列表
git stash list
# 查看暂存内容
git stash show
git stash show -p # 显示详细差异
恢复和管理暂存#
# 恢复最新的暂存
git stash pop
# 恢复指定的暂存
git stash pop stash@{1}
# 应用暂存但不删除
git stash apply
git stash apply stash@{1}
# 删除暂存
git stash drop
git stash drop stash@{1}
# 清空所有暂存
git stash clear
# 从暂存创建分支
git stash branch new-branch-name stash@{1}
部分暂存#
# 交互式暂存
git stash -p
# 只暂存已跟踪的文件
git stash --keep-index
# 暂存特定文件
git stash push path/to/file.txt
高级技巧#
标签管理#
创建标签#
# 创建轻量标签
git tag v1.0.0
# 创建附注标签
git tag -a v1.0.0 -m "Release version 1.0.0"
# 为指定提交创建标签
git tag -a v1.0.0 abc1234 -m "Release version 1.0.0"
# 查看所有标签
git tag
# 查看匹配模式的标签
git tag -l "v1.*"
管理标签#
# 查看标签信息
git show v1.0.0
# 推送标签到远程
git push origin v1.0.0
# 推送所有标签
git push origin --tags
# 删除本地标签
git tag -d v1.0.0
# 删除远程标签
git push origin --delete v1.0.0
子模块(Submodules)#
添加子模块#
# 添加子模块
git submodule add https://github.com/user/repo.git path/to/submodule
# 初始化子模块
git submodule init
# 更新子模块
git submodule update
# 一步完成初始化和更新
git submodule update --init --recursive
管理子模块#
# 查看子模块状态
git submodule status
# 更新子模块到最新提交
git submodule update --remote
# 进入子模块目录进行操作
cd path/to/submodule
git checkout main
git pull
# 返回主项目并提交子模块更新
cd ../..
git add path/to/submodule
git commit -m "Update submodule"
工作树(Worktree)#
工作树允许您同时检出多个分支到不同的目录。
# 创建新的工作树
git worktree add ../feature-branch feature-branch
# 创建新分支的工作树
git worktree add -b new-feature ../new-feature
# 查看所有工作树
git worktree list
# 删除工作树
git worktree remove ../feature-branch
# 清理工作树引用
git worktree prune
网络和安全配置#
网络配置#
代理设置#
# 设置 HTTP 代理
git config --global http.proxy http://proxy.company.com:8080
git config --global https.proxy https://proxy.company.com:8080
# 设置 SOCKS 代理
git config --global http.proxy socks5://127.0.0.1:1080
# 为特定域名设置代理
git config --global http.https://github.com.proxy http://proxy.company.com:8080
# 取消代理设置
git config --global --unset http.proxy
git config --global --unset https.proxy
SSL 配置#
# 跳过 SSL 证书验证(不推荐)
git config --global http.sslVerify false
# 为特定域名跳过 SSL 验证
git config --global http.https://internal-git.company.com.sslVerify false
# 设置自定义 CA 证书
git config --global http.sslCAInfo /path/to/ca-bundle.crt
# 设置客户端证书
git config --global http.sslCert /path/to/client.crt
git config --global http.sslKey /path/to/client.key
超时设置#
# 设置连接超时
git config --global http.timeout 30
# 设置低速传输超时
git config --global http.lowSpeedLimit 1000
git config --global http.lowSpeedTime 300
性能优化#
大文件处理#
# 启用 Git LFS(Large File Storage)
git lfs install
# 跟踪大文件类型
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "*.mp4"
# 查看 LFS 跟踪的文件
git lfs ls-files
# 查看 LFS 状态
git lfs status
仓库优化#
# 垃圾回收
git gc
# 积极的垃圾回收
git gc --aggressive
# 清理不可达的对象
git prune
# 查看仓库大小
git count-objects -vH
# 查找大文件
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 | tail -10
故障排除#
常见问题解决#
合并冲突#
# 查看冲突文件
git status
# 手动解决冲突后
git add conflicted-file.txt
git commit
# 使用合并工具
git mergetool
# 中止合并
git merge --abort
# 查看冲突的详细信息
git diff
分离头指针(Detached HEAD)#
# 当前状态:分离头指针
git status
# 创建新分支保存更改
git checkout -b new-branch-name
# 或者切换回原分支(丢弃更改)
git checkout main
误删分支恢复#
# 查看引用日志
git reflog
# 恢复删除的分支
git checkout -b recovered-branch abc1234
# 或者直接重新创建分支
git branch recovered-branch abc1234
推送被拒绝#
# 原因:远程有新的提交
# 解决方案1:拉取并合并
git pull origin main
git push origin main
# 解决方案2:拉取并变基
git pull --rebase origin main
git push origin main
# 解决方案3:强制推送(危险)
git push --force-with-lease origin main
调试和诊断#
查看详细信息#
# 启用详细输出
git -v command
# 查看 Git 版本
git --version
# 查看 Git 配置路径
git config --list --show-origin
# 查看环境变量
git var -l
性能分析#
# 分析命令执行时间
time git command
# 启用性能跟踪
GIT_TRACE=1 git command
GIT_TRACE_PERFORMANCE=1 git command
GIT_TRACE_SETUP=1 git command
团队协作最佳实践#
提交规范#
提交信息格式#
# 推荐格式
<type>(<scope>): <subject>
<body>
<footer>
# 示例
feat(auth): add OAuth2 integration
Implement OAuth2 authentication flow with Google and GitHub providers.
This allows users to sign in using their existing accounts.
Closes #123
提交类型#
feat: 新功能fix: 修复 bugdocs: 文档更新style: 代码格式化refactor: 重构test: 测试相关chore: 构建过程或辅助工具的变动
分支策略#
Git Flow#
# 主分支
main # 生产分支
develop # 开发分支
# 辅助分支
feature/* # 功能分支
release/* # 发布分支
hotfix/* # 热修复分支
GitHub Flow#
# 简化流程
main # 主分支
feature/* # 功能分支(直接从 main 创建,完成后合并回 main)
代码审查#
Pull Request 工作流#
# 1. 创建功能分支
git checkout -b feature/new-feature
# 2. 开发并提交
git add .
git commit -m "feat: implement new feature"
# 3. 推送分支
git push origin feature/new-feature
# 4. 创建 Pull Request
# 5. 代码审查
# 6. 合并到主分支
# 7. 删除功能分支
git branch -d feature/new-feature
git push origin --delete feature/new-feature
自动化和工具#
Git Hooks#
常用钩子#
# 提交前检查
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
# 运行代码检查
npm run lint
npm run test
EOF
# 提交信息检查
cat > .git/hooks/commit-msg << 'EOF'
#!/bin/sh
# 检查提交信息格式
commit_regex='^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,50}'
if ! grep -qE "$commit_regex" "$1"; then
echo "Invalid commit message format"
exit 1
fi
EOF
# 设置执行权限
chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/commit-msg
别名配置#
# 常用别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
# 高级别名
git config --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"
git config --global alias.unstash 'stash pop'
git config --global alias.uncommit 'reset --soft HEAD~1'
总结与最佳实践#
核心原则#
- 频繁提交: 保持小而频繁的提交,便于追踪和回滚
- 清晰的提交信息: 使用规范的提交信息格式
- 分支管理: 合理使用分支,保持主分支的稳定性
- 代码审查: 通过 Pull Request 进行代码审查
- 备份重要数据: 定期推送到远程仓库
安全建议#
- 使用 SSH 密钥: 避免在命令行中暴露密码
- 谨慎使用强制推送: 使用
--force-with-lease替代--force - 保护敏感信息: 使用
.gitignore忽略敏感文件 - 定期更新: 保持 Git 版本的更新
性能优化#
- 合理使用 .gitignore: 避免跟踪不必要的文件
- 定期清理: 使用
git gc清理仓库 - 浅克隆: 对于大仓库使用
--depth参数 - LFS 支持: 对大文件使用 Git LFS
学习资源#
- 官方文档: https://git-scm.com/doc
- Pro Git 书籍: https://git-scm.com/book
- 交互式学习: https://learngitbranching.js.org/
- Git 速查表: https://training.github.com/downloads/github-git-cheat-sheet/
现代化 Git 工作流#
GitHub CLI 集成#
GitHub CLI 是现代开发者的强大工具:
# 安装 GitHub CLI
# macOS: brew install gh
# Windows: winget install GitHub.cli
# Linux: 参考官方文档
# 认证
gh auth login
# 克隆仓库
gh repo clone owner/repo
# 创建仓库
gh repo create my-new-repo --public
gh repo create my-new-repo --private --clone
# Pull Request 操作
gh pr create --title "Add new feature" --body "Description"
gh pr list
gh pr view 123
gh pr checkout 123
gh pr merge 123
# Issue 操作
gh issue create --title "Bug report" --body "Description"
gh issue list
gh issue view 123
gh issue close 123
# 发布管理
gh release create v1.0.0 --title "Version 1.0.0" --notes "Release notes"
gh release list
gh release download v1.0.0
现代化配置#
推荐的全局配置#
# 现代化的 Git 配置
cat > ~/.gitconfig << 'EOF'
[user]
name = Your Name
email = your.email@example.com
[init]
defaultBranch = main
[core]
editor = code --wait # 使用 VS Code 作为编辑器
autocrlf = input # Linux/Mac
# autocrlf = true # Windows
ignorecase = false
precomposeunicode = true
[pull]
rebase = true # 默认使用 rebase 而不是 merge
[push]
default = simple
autoSetupRemote = true # 自动设置远程分支
[merge]
tool = vscode
conflictstyle = diff3
[mergetool "vscode"]
cmd = code --wait $MERGED
[diff]
tool = vscode
[difftool "vscode"]
cmd = code --wait --diff $LOCAL $REMOTE
[rebase]
autoStash = true # 自动暂存未提交的更改
[fetch]
prune = true # 自动清理已删除的远程分支
[status]
showUntrackedFiles = all
[color]
ui = auto
[alias]
# 常用简写
st = status
co = checkout
br = branch
ci = commit
sw = switch
# 高级别名
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
unstage = reset HEAD --
uncommit = reset --soft HEAD~1
amend = commit --amend --no-edit
# 分支操作
recent = branch --sort=-committerdate
cleanup = "!git branch --merged | grep -v '\\*\\|main\\|develop' | xargs -n 1 git branch -d"
# 查看操作
who = shortlog -sn
what = show --pretty="format:" --name-only
# 同步操作
sync = "!git fetch origin && git rebase origin/main"
update = "!git pull origin main && git push origin main"
EOF
高级工作流场景#
多人协作冲突解决#
# 场景:多人同时修改同一文件
# 1. 获取最新代码
git fetch origin
# 2. 查看冲突情况
git log --oneline --graph origin/main..HEAD
git log --oneline --graph HEAD..origin/main
# 3. 使用 rebase 解决冲突
git rebase origin/main
# 4. 如果有冲突,逐个解决
# 编辑冲突文件,然后:
git add conflicted-file.txt
git rebase --continue
# 5. 推送解决后的代码
git push --force-with-lease origin feature-branch
大型项目的分支管理#
# 创建功能分支
git checkout -b feature/JIRA-123-user-authentication
# 定期同步主分支
git fetch origin
git rebase origin/main
# 提交前的最后检查
git log --oneline origin/main..HEAD # 查看即将推送的提交
git diff origin/main...HEAD # 查看所有更改
# 推送并创建 PR
git push origin feature/JIRA-123-user-authentication
gh pr create --title "JIRA-123: Implement user authentication" \
--body "Implements OAuth2 authentication with Google and GitHub providers"
热修复工作流#
# 从生产分支创建热修复分支
git checkout main
git pull origin main
git checkout -b hotfix/critical-security-fix
# 进行修复
git add .
git commit -m "fix: resolve critical security vulnerability"
# 推送热修复
git push origin hotfix/critical-security-fix
# 创建紧急 PR
gh pr create --title "URGENT: Critical security fix" \
--body "Fixes critical security vulnerability" \
--label "urgent,security"
# 合并后,同步到开发分支
git checkout develop
git pull origin develop
git merge main
git push origin develop
代码质量保证#
Pre-commit Hooks 配置#
# 安装 pre-commit
pip install pre-commit
# 创建 .pre-commit-config.yaml
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-merge-conflict
- id: check-json
- id: pretty-format-json
args: ['--autofix']
- id: check-toml
- id: check-xml
- id: mixed-line-ending
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.44.0
hooks:
- id: eslint
files: \.(js|ts|jsx|tsx)$
types: [file]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0
hooks:
- id: prettier
files: \.(js|ts|jsx|tsx|json|css|md)$
EOF
# 安装 hooks
pre-commit install
# 手动运行所有文件的检查
pre-commit run --all-files
提交信息规范化#
# 安装 commitizen
npm install -g commitizen cz-conventional-changelog
# 配置 commitizen
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
# 使用 commitizen 提交
git add .
git cz # 或者 npx cz
# 安装 commitlint
npm install -g @commitlint/cli @commitlint/config-conventional
# 创建 commitlint 配置
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
# 添加 commit-msg hook
cat > .git/hooks/commit-msg << 'EOF'
#!/bin/sh
npx commitlint --edit $1
EOF
chmod +x .git/hooks/commit-msg
性能优化和维护#
仓库健康检查#
#!/bin/bash
# Git 仓库健康检查脚本
echo "=== Git Repository Health Check ==="
# 检查仓库大小
echo "Repository size:"
du -sh .git
# 检查对象数量
echo -e "\nObject count:"
git count-objects -v
# 检查大文件
echo -e "\nLargest files in repository:"
git rev-list --objects --all | \
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
sed -n 's/^blob //p' | \
sort --numeric-sort --key=2 | \
tail -10
# 检查分支状态
echo -e "\nBranch status:"
git for-each-ref --format='%(refname:short) %(committerdate)' refs/heads | sort -k2
# 检查远程分支
echo -e "\nRemote branches:"
git branch -r --merged main | grep -v main
# 检查未推送的提交
echo -e "\nUnpushed commits:"
git log --branches --not --remotes --oneline
# 运行垃圾回收
echo -e "\nRunning garbage collection..."
git gc --auto
echo -e "\nHealth check completed!"
自动化清理脚本#
#!/bin/bash
# Git 仓库清理脚本
echo "=== Git Repository Cleanup ==="
# 清理已合并的本地分支
echo "Cleaning up merged branches..."
git branch --merged main | grep -v "main\|develop" | xargs -n 1 git branch -d
# 清理远程分支引用
echo "Pruning remote branches..."
git remote prune origin
# 清理 reflog
echo "Cleaning reflog..."
git reflog expire --expire=30.days --all
# 运行垃圾回收
echo "Running garbage collection..."
git gc --aggressive --prune=now
# 检查仓库完整性
echo "Checking repository integrity..."
git fsck --full
echo "Cleanup completed!"
团队协作进阶#
代码审查最佳实践#
# 创建审查友好的提交
# 1. 逻辑分组提交
git add file1.js file2.js
git commit -m "feat(auth): add login validation logic"
git add test1.js test2.js
git commit -m "test(auth): add unit tests for login validation"
git add docs/auth.md
git commit -m "docs(auth): update authentication documentation"
# 2. 使用交互式 rebase 整理提交历史
git rebase -i HEAD~3
# 3. 创建详细的 PR 描述
gh pr create --title "feat(auth): implement OAuth2 authentication" \
--body "## Changes
- Add OAuth2 authentication flow
- Implement Google and GitHub providers
- Add comprehensive unit tests
- Update documentation
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
## Screenshots
<!-- 登录流程截图(已移除:截图文件不存在) -->
Closes #123"
发布管理#
# 语义化版本发布流程
# 1. 确保在主分支
git checkout main
git pull origin main
# 2. 创建发布分支
git checkout -b release/v1.2.0
# 3. 更新版本号
npm version minor # 或者手动更新 package.json
# 4. 生成变更日志
npx conventional-changelog -p angular -i CHANGELOG.md -s
# 5. 提交版本更新
git add .
git commit -m "chore(release): bump version to 1.2.0"
# 6. 合并到主分支
git checkout main
git merge --no-ff release/v1.2.0
# 7. 创建标签
git tag -a v1.2.0 -m "Release version 1.2.0"
# 8. 推送到远程
git push origin main
git push origin v1.2.0
# 9. 创建 GitHub 发布
gh release create v1.2.0 --title "Version 1.2.0" --notes-file CHANGELOG.md
# 10. 清理发布分支
git branch -d release/v1.2.0
故障恢复高级技巧#
数据恢复场景#
# 场景1:恢复误删的文件
git log --diff-filter=D --summary | grep delete
git checkout <commit-before-deletion> -- <deleted-file>
# 场景2:恢复误删的分支
git reflog --all | grep <branch-name>
git checkout -b <branch-name> <commit-hash>
# 场景3:恢复误删的提交
git reflog
git cherry-pick <commit-hash>
# 场景4:恢复到某个时间点
git log --since="2023-01-01" --until="2023-01-02" --oneline
git checkout <commit-hash>
git checkout -b recovery-branch
# 场景5:恢复被覆盖的文件内容
git log -p -- <file-path> | head -50
git show <commit-hash>:<file-path> > recovered-file.txt
高级重写历史#
# 使用 filter-branch 重写历史(谨慎使用)
# 从历史中完全删除文件
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch path/to/sensitive-file' \
--prune-empty --tag-name-filter cat -- --all
# 使用 BFG Repo-Cleaner(推荐)
# 下载 bfg.jar
java -jar bfg.jar --delete-files sensitive-file.txt
java -jar bfg.jar --strip-blobs-bigger-than 100M
git reflog expire --expire=now --all && git gc --prune=now --aggressive
# 修改作者信息
git filter-branch --env-filter '
OLD_EMAIL="old@email.com"
CORRECT_NAME="Correct Name"
CORRECT_EMAIL="correct@email.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
总结与展望#
Git 的未来发展#
- 性能优化: 持续改进大仓库的性能
- 用户体验: 更友好的命令行界面和错误信息
- 安全增强: 更强的安全特性和验证机制
- 云集成: 更好的云服务集成支持
持续学习建议#
- 实践为主: 在实际项目中应用所学技巧
- 关注更新: 跟踪 Git 的新版本和新特性
- 社区参与: 参与开源项目,学习最佳实践
- 工具探索: 尝试新的 Git 相关工具和服务
最终建议#
Git 是现代软件开发的基石,掌握它不仅能提高个人效率,更能促进团队协作。从基础命令开始,逐步深入高级特性,结合实际项目需求,您将能够充分发挥 Git 的强大功能。
记住:好的版本控制习惯是优秀开发者的标志之一。
通过掌握这些 Git 技巧和最佳实践,您将能够更高效地进行版本控制和团队协作。记住,Git 是一个强大的工具,需要时间和实践来完全掌握。建议从基础命令开始,逐步学习高级功能,并在实际项目中应用这些技巧。
