Git 是一个功能强大的版本控制系统,提供了丰富的工具和命令来优化开发工作流程。本章将介绍一些 Git 的高效技巧和常见问题的解决方案,包括交互式变更、垃圾回收、版本库拆分、提交恢复、SVN 转换技巧、文件管理等,帮助开发者更高效地使用 Git。
21.1 对脏的工作目录灵活进行交互式变更
当工作目录中有未提交的修改时,可以使用 git stash
临时保存更改,以便进行其他操作。
21.1.1 暂存未提交的更改
git stash
然后可以安全地切换分支、拉取最新代码等。
21.1.2 交互式选择暂存的部分更改
git add -p
Git 会逐个显示未提交的代码块,并询问是否暂存 (y
暂存, n
跳过, s
分割, e
编辑)。
21.1.3 恢复暂存的更改
git stash pop
或者仅应用暂存但不删除存储:
git stash apply
21.2 删除残余的编辑器文件
当使用 IDE(如 VS Code、JetBrains IDE、Vim)时,Git 可能会检测到不必要的临时文件。这些文件应添加到 .gitignore
中,例如:
# VS Code
.vscode/
# JetBrains
.idea/
# Vim
*.swp
可以使用 git clean
删除未被 Git 追踪的文件:
git clean -df
⚠️ 注意:此命令会永久删除未追踪的文件,请谨慎使用!
21.3 垃圾回收
Git 会保留所有的对象(提交、树、文件等),即使它们已被删除。可以使用 git gc
进行垃圾回收,以减少 Git 仓库的体积:
git gc --aggressive --prune=now
查看当前存储的松散对象:
git count-objects -vH
21.4 拆分版本库
如果希望从现有版本库中拆分一个子项目到新的 Git 仓库,可以使用 git filter-repo
:
git filter-repo --path subproject/ --target-directory new-repo/
然后进入 new-repo/
目录,初始化新的 Git 仓库:
cd new-repo
git init
git remote add origin <new-repo-url>
git push -u origin main
21.5 恢复提交的小贴士
如果不小心 git reset --hard
,可以使用 git reflog
恢复丢失的提交:
git reflog
找到丢失提交的哈希,然后执行:
git checkout -b recovery-branch <commit-hash>
21.6 转换 Subversion 的技巧
21.6.1 迁移建议
迁移 SVN 到 Git 时,可以使用 git svn clone
逐步迁移:
git svn clone --stdlayout https://svn.example.com/repo project
21.6.2 删除 SVN 导入后的 trunk
当从 SVN 迁移到 Git 时,通常会保留 trunk/
目录,但在 Git 中不需要,可以使用 git filter-repo
删除它:
git filter-repo --path trunk/ --invert-paths
21.6.3 删除 SVN 提交 ID
SVN 迁移后,Git 提交信息中可能会带有 git-svn-id
,可以使用 git filter-repo
去除:
git filter-repo --replace-text <(echo "git-svn-id==>REMOVE<")
21.7 操作来自两个版本库的分支
在 Git 里,可以从两个不同的远程仓库拉取分支。例如:
git remote add upstream https://github.com/example/repo.git
git fetch upstream
git checkout -b feature upstream/main
21.8 从上游变基中恢复
如果上游仓库发生了变基(git rebase
),可能会导致本地提交丢失。这时可以使用 git reflog
找回:
git reflog
git checkout <commit-hash>
21.9 定制 Git 命令
Git 允许用户创建自定义命令。例如,可以创建 git undo
命令来撤销最近一次提交:
echo -e "#!/bin/bash\n git reset --soft HEAD~1" > ~/bin/git-undo
chmod +x ~/bin/git-undo
现在可以使用 git undo
来撤销提交:
git undo
21.10 快速查看变更
快速查看最近 5 次提交的变更内容:
git log -p -5
仅查看哪些文件发生了变更:
git diff --name-only HEAD~1
21.11 清理
清理未被 Git 追踪的文件和目录(⚠️ 无法恢复):
git clean -fd
21.12 使用 git grep
来搜索版本库
Git 内置的 grep
命令可以高效搜索代码:
git grep "TODO"
仅搜索特定分支:
git grep "BUGFIX" main
21.13 更新和修改 ref
重命名分支:
git branch -m old-branch new-branch
21.14 跟踪和忽略的文件
有时需要让 Git 忽略已提交的文件(但不删除它们):
git update-index --assume-unchanged <file>
如果想要 Git 重新跟踪该文件:
git update-index --no-assume-unchanged <file>
21.15 保留但不追踪文件
如果希望保留文件但 Git 不再跟踪,可以使用 git rm --cached
:
git rm --cached secret-config.json
git commit -m "停止追踪 secret-config.json"
然后添加到 .gitignore
以防止将来再次提交:
echo "secret-config.json" >> .gitignore
git add .gitignore
git commit -m "添加 secret-config.json 到 .gitignore"
21.16 你来过这里吗?
如果想要知道一个提交是否在当前分支中,可以使用 git branch --contains
:
git branch --contains <commit-hash>
如果想知道某个提交是否已经合并到 main
,可以使用:
git branch --merged | grep main
结论
本章介绍了一系列 Git 提示、技巧和技术,包括:
- 优化日常 Git 操作(交互式暂存、垃圾回收、快速查看变更)。
- 高级管理(拆分版本库、恢复提交、定制 Git 命令)。
- SVN 迁移技巧(删除
trunk
、清理 SVN ID)。
掌握这些技巧,可以极大地提高 Git 的使用效率,使版本控制更加灵活和高效。