Git~Git 使用详尽教程 — 从安装到工作流、真实场景与常见坑

Git 使用详尽教程 — 从安装到工作流、真实场景与常见坑

目录

  1. 核心概念速览
  2. 安装与首次配置(简要)
  3. 日常工作流(示例命令 + 场景演示)
  4. 分支策略与团队协作(GitHub/GitLab 风格)
  5. 合并、变基与冲突处理(详细步骤)
  6. 回退、修复与历史重写(危险操作要谨慎)
  7. 常见工作场景与实战示例(hotfix、同步 fork、cherry-pick)
  8. 常见坑 + 逐条解决方案(可复制命令)
  9. 进阶话题速览(submodule、LFS、hooks、gitattributes)
  10. 精简常用命令速查表(便于复制)

1. 核心概念

  • commit(提交):记录代码快照,每次提交有唯一 SHA-id。
  • HEAD:当前检出的提交或分支的指针(“我现在在时间线的哪儿”)。
  • Index / Staging area(暂存区)git add 后的下一站,git commit 从这里生成提交。
  • branch(分支):轻量指针,指向某个提交,方便并行开发。
  • remote(远程):常见如 origin(你 fork/clone 来的那个仓库),upstream(上游仓库)。
  • merge / rebase:两种把分支合并回主线的思路,产生历史差异(见后文)。

2. 安装与首次配置

(你已经有之前的安装文档,这里只列核心配置)

# 全局用户名与邮箱(必须)
git config --global user.name "你的名字"
git config --global user.email "你的邮箱@example.com"

# 设置默认编辑器(例如 VSCode)
git config --global core.editor "code --wait"

# 开启彩色输出
git config --global color.ui auto

# 全局 .gitignore
git config --global core.excludesfile ~/.gitignore_global

~/.gitignore_global 填上 OS / 编辑器常见垃圾文件(.DS_Store, Thumbs.db, *.log 等)。


3. 日常工作流(Feature-branch,最常见)

目标:主分支(main/master)保持可发布状态;开发在短生命周期分支上,完成后通过 PR/MR 合并。

示例:创建 feature 分支 → 本地开发 → 推送 → 发 PR。

# 从最新的 main 开始
git checkout main
git pull origin main        # 或 git fetch && git merge origin/main

# 新建分支并切换
git switch -c feature/xxx

# 开发过程中(分阶段提交)
git add file1 file2
git commit -m "feat: 增加 xxx 功能 - explain briefly"
# 多次提交...

# 推送到远程并建立上游关联
git push -u origin feature/xxx

# 在 GitHub/GitLab 上创建 PR,等待 Code Review

工作中常见建议

  • 提交小而原子(单一变更目的),方便回退与 review。
  • PR 描述完整(改动目的、如何测试、截图/日志/性能影响)。
  • 尽量让 PR 不超过一天未合并(避免长期分支冲突)。

4. 分支策略与团队协作

  • GitHub Flow(推荐轻量):主分支始终可部署,短小 feature 分支 + PR。
  • GitLab Flow / GitFlow(正式/较重):有 develop, release, hotfix 等分支,适合版本管理更复杂的团队。
  • Trunk-based:非常短-lived 分支,鼓励频繁合并到 trunk,CI 强制测试。

企业里通常:保护 main(require PR、CI 通过、review),禁止强推(force push)。


5. 合并、变基与冲突处理

merge vs rebase(核心对比)

  • merge:把两个历史合并,保留分支点,常见命令 git merge feature
    优点:历史真实,保留并行信息;缺点:历史较“分叉”。
  • rebase:把分支上的提交“搬到”目标分支后面,得到线性历史,命令 git rebase main
    优点:清爽线性历史;缺点:改变提交 SHA —— 不要对公共分支做 rebase(会给他人制造痛苦)。

处理冲突(示例:rebase 中发生冲突)

  1. 在 feature 分支上:git rebase main
  2. 若冲突发生,Git 会停下,git status 会显示冲突文件。
  3. 手动编辑文件,解决冲突(删除 <<<<<<< 标记)
  4. git add <file> 标记解决
  5. git rebase --continue 继续
  6. 如要放弃变基:git rebase --abort

合并冲突常见技巧:

  • 先 pull 最新 main 并 rebase 本地分支,避免大型 PR 冲突积累。
  • 使用 git mergetool 或 IDE 的 merge 工具(VS Code、IntelliJ)来可视化解决。
  • 如果冲突内容很复杂,可创建临时分支保存当前状态,然后回滚重做。

合并完成后:若使用 rebase 并已推送到远程,需要 git push --force-with-lease(首选 --force-with-lease 而非 --force,更安全)。


6. 回退、修复与历史重写(细节与安全)

常见场景与对应操作

  1. 改动还没提交(工作区修改)
    放弃修改:

    git restore <file>         # 等价于旧的 git checkout -- file
    
  2. 已暂存但未提交(staged)
    取消暂存:

    git reset <file>
    
  3. 想修改最后一次提交的内容或信息(还未 push)

    git commit --amend -m "新的提交信息"
    

    若已经 push,修改历史需谨慎并通知团队(见下)。

  4. 回退已经推送到公共分支的坏提交(推荐)
    使用 git revert 生成一个新提交来撤销之前的提交(安全,不改变历史)。

    git revert <commit-sha>
    git push
    
  5. 彻底删除本地历史(危险)
    git reset --hard <sha> 会丢弃工作区和暂存的修改。谨慎使用

  6. 误 push 后想重写历史

    • 先确保所有协作者知晓;

    • 推荐使用 git push --force-with-lease(比 --force 更安全);

    • 使用 reflog 恢复丢失的提交(若误操作):

      git reflog
      git checkout -b recover <sha>
      

7. 常见工作场景与实战示例

场景 A:主分支紧急 bug(hotfix)

  1. 在本地从 main 建 hotfix 分支:

    git checkout main
    git pull origin main
    git switch -c hotfix/critical-fix
    # 修复,提交
    git commit -am "fix: 修复生产紧急 bug"
    git push -u origin hotfix/critical-fix
    
  2. 在 remote 上创建 PR → 通过后合并到 main(通常使用 merge commit 或 squash,按团队规则)。

  3. 合并后把 hotfix 合并回 develop(若你使用 GitFlow)。

场景 B:你 fork 了上游仓库,需要与上游同步

# 添加上游
git remote add upstream git@github.com:OriginalOwner/Repo.git

# 同步 main
git fetch upstream
git checkout main
git merge upstream/main
git push origin main

或更常用的保持线性:

git fetch upstream
git checkout feature/xxx
git rebase upstream/main
# 处理冲突后
git push --force-with-lease

场景 C:在多人协作中把别人的单个提交拣到你的分支(cherry-pick)

git checkout feature/xxx
git fetch origin
git cherry-pick <commit-sha>
# 解决冲突 → git add ... → git cherry-pick --continue

8. 常见坑 + 逐条解决方案(工作中最容易踩的雷)

这些是团队与个人在实际项目里最常遇到的问题,并附上可复制命令与建议。

坑 1:误把密码/密钥提交到仓库(机密泄露)

步骤(紧急)

  1. 立刻撤销/吊销该秘钥(最重要)。

  2. 在本地移除该文件并从历史中删除:

    • 推荐工具:git filter-repo(现代、安全、快速)或 bfg-repo-cleaner。示例(filter-repo 要另行安装):

      git filter-repo --path path/to/secret.txt --invert-paths
      
    • 或用 bfg:bfg --delete-files secret.txt

  3. 强制推送到远程(并通知团队):

    git push --force --all
    git push --force --tags
    
  4. 更新 README 或通知安全负责人。
    注意:即便从 Git 历史删除,第三方镜像/缓存可能仍留存,必须换密钥并审计。

坑 2:在公共分支上做 rebase 并强推,导致他人历史被破坏

修复

  • git reflog 找到被覆盖的提交,用 git checkout -b restore <sha> 恢复;协调团队合并回去。
    预防:设置分支保护(禁止强推),仅允许 PR 合并。

坑 3:换行符(CRLF/LF)导致大量文件变动

解决

  • 在 repo 根放 .gitattributes

    * text=auto
    *.sh eol=lf
    
  • Windows 用户:git config --global core.autocrlf true,Linux/macOS 用户:git config --global core.autocrlf input

  • 如果仓库已经混乱,参考 .gitattributes 后执行一次干净重检出:

    git rm --cached -r .
    git reset --hard
    

坑 4:子模块(submodule)更新后别忘了提交指针

要点:子模块是记录某个提交 SHA,不会自动更新父仓库。步骤:

git submodule update --init --recursive  # 初始化
# 进入子模块更新
cd path/to/submodule
git fetch && git checkout some-commit
# 返回父 repo,提交子模块指针变更
cd ../..
git add path/to/submodule
git commit -m "update submodule pointer"
git push

坑 5:仓库体积飙升(大文件、历史垃圾)

临时清理

git gc --aggressive --prune=now
git repack -ad

如果要从历史彻底移除大文件,请使用 git filter-repobfg,并强推。

坑 6:stash 消失或忘了 stash 内容在何处

  • 查看 stash 列表:git stash list

  • 恢复某个 stash 到新分支(安全):

    git stash branch recover-stash stash@{2}
    

坑 7:detached HEAD(检出 tag 导致)

表现:提示你处在 detached HEAD,提交不会更新任何分支。
做法

git switch -c my-fix-branch    # 在当前点创建分支并切换

坑 8:误删分支后需要恢复

使用 reflog 找提交 SHA,然后:

git checkout -b restore-branch <sha>

9. 进阶话题:实用建议与示例

Git LFS(大文件)

  • 用于管理二进制大文件(模型、媒体),需要安装 git-lfs

    git lfs install
    git lfs track "*.psd"
    git add .gitattributes
    git add file.psd
    git commit -m "add large file"
    
  • 注意:LFS 仍会占用 server 存储配额(如 GitHub)。

钩子(hooks)

  • 本地 .git/hooks/pre-commit 可做 lint、测试:
    示例(简单):

    #!/bin/sh
    # 检查 Python 文件是否包含 TODO
    if git diff --cached --name-only | grep '\.py$' >/dev/null; then
      if git diff --cached | grep 'TODO' >/dev/null; then
        echo "Found TODO in staged Python files. Please remove."
        exit 1
      fi
    fi
    
  • 推荐使用 pre-commit 框架统一团队 hooks(跨平台,易配置)。

.gitattributes(控制合并/换行/二进制)

  • 强制某些文件使用特定 EOL、合并策略,或标记为二进制防止自动合并。

针对 CI 与保护分支的团队做法

  • 启用 branch protection:要求 PR、CI 通过、至少一人 review、禁止 force push。
  • 在合并策略上规定 squash merge / merge commit / rebase and merge,并写入 CONTRIBUTING.md。

10. 精简常用命令速查(挑最常用的 40 条)

git --version
git init
git clone <url>
git status
git add <file>
git add .
git commit -m "msg"
git commit --amend
git log --oneline --graph
git diff
git diff --staged
git restore <file>
git reset <file>
git branch
git branch -d <branch>
git switch <branch>
git switch -c <branch>
git checkout <branch>      # 旧命令等价于 switch
git merge <branch>
git rebase <branch>
git rebase -i HEAD~N
git cherry-pick <sha>
git revert <sha>
git fetch
git pull
git pull --rebase
git push
git push -u origin <branch>
git push --force-with-lease
git remote -v
git remote add upstream <url>
git stash
git stash pop
git stash branch <name>
git tag -a v1.0 -m "msg"
git show <sha>
git reflog
git gc

附:提交信息模板

采用简洁且有含义的提交风格,便于生成 changelog:

<type>(<scope>): <简短描述>

可选正文(为什么这么改,影响哪些地方)
BREAKING CHANGE: <说明破坏性改动>

常用 type: feat, fix, docs, style, refactor, perf, test, chore

示例:

feat(auth): add OAuth2 login

支持 Google / GitHub 登录,增加 token 刷新逻辑。

结语

Git 是把你工作中“时间”和“版本”组织起来的超级工具,但它不是魔法:良好的分支策略 + 小而频繁的提交 + 清晰的 PR 描述 + 保护主分支,能把绝大多数麻烦扼杀在摇篮里。遇到历史修复或强推类操作,先冷静、通知团队并先备份(git reflog 能救你很多次)。

作者:FeiLink
本文部分内容由 AI 辅助生成,并经人工整理与验证,仅供参考学习,欢迎指出错误与不足之处。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值