10 个你今天就应该开始使用的全新 Git 命令
https://appwrite.io/blog/post/10-git-commands-you-should-start-using#4-git-sparse-checkout-efficiently-handle-large-repositories
10 个你今天就应该开始使用的全新 Git 命令
1. git switch – 更安全的切换分支方式
在 Git 2.23 之前,git checkout 是切换分支的主要命令,但它能做的事情远不止于此:用它可以恢复文件、创建分支或检出特定提交。这种强大也带来了一定混淆——有时你只是想单纯地切换分支,却可能无意间对文件做出更改。
为此,Git 2.23 引入了 git switch,用以专注于分支操作,让命令职责更加清晰:
# 切换到其他分支
git switch feature-branch
# 创建并切换到新分支
git switch -c new-branch
这一改动能有效降低误操作的风险,比如不小心覆盖了文件或进行意外更改。如果你之前在使用 git checkout 时会担心“踩坑”,那么 git switch 就能让切换分支简化许多。
2. git restore – 安全地撤销更改
过去想撤销更改时,可能会使用 git checkout 来还原文件,或用 git reset 来移动分支 HEAD。但使用不当的话,这两条命令都有可能改变你的分支状态:git reset 会移动你当前分支的 HEAD;git checkout 可能切换分支,或者检出不同的提交,从而打断当前分支的工作流程。
Git 2.23 推出了 git restore,它只专注于“撤销文件的更改”,为工作区或暂存区提供安全明了的还原方式,也让文件操作和分支管理区分得更清楚:
# 丢弃工作区中的修改
git restore main.js
# 从暂存区中移除修改
git restore --staged main.js
对于 Git 新手或者需要精准操作的场合,这尤其好用。这样,你无需担心会意外切换分支或重置提交,就能放心地撤销文件修改。
3. git maintenance – 自动化地保持仓库健康
随着仓库规模的不断增长,可能会出现性能下降的情况。诸如 git fetch、git status 或 git log 等操作都会变慢,而且仓库中会积累一些无用的数据。以前,你需要手动执行类似 git gc(垃圾回收)或 git repack 命令来优化仓库。
Git 2.29 引入了 git maintenance 来自动完成这些维护工作:
# 启用自动维护
git maintenance start
# 立即运行清理任务
git maintenance run
其背后的原理主要包括:
• 垃圾回收 (Garbage Collection):移除无法再通过任何引用访问的对象,比如在 rebase 或删除分支时被丢弃的提交。
• Repacking:合并分散的打包文件(packfile),提升存储效率。
• 提交图更新 (Commit Graph Updates):优化提交历史的遍历速度,加快 git log 和 git blame 等命令的执行。
使用 git maintenance 能让你无需反复手动维护,就能保持仓库的高效和整洁。
4. git sparse-checkout – 高效处理大型仓库
Monorepo(单体式仓库)在管理多个项目时很有用,但如果你只需要其中某个子目录的内容,却要被迫完整克隆整个仓库,那就显得很低效。为此,Git 2.25 推出了 git sparse-checkout:
# 启用 sparse-checkout 模式
git sparse-checkout init
# 只获取指定的目录
# 可用空格分隔多个目录
git sparse-checkout set services/ docs/
使用 git sparse-checkout 你可以只包含需要的目录或文件,其余的部分不会出现在工作区中。对于在同一个 monorepo 中协作、但只关注特定业务模块的团队而言,这能大幅节省时间和磁盘空间。
5. git log --remerge-diff:更好地理解合并
Merge 提交通常只告诉我们合并了哪个分支,但并不总能展示合并过程中引入的具体更改,尤其是在有冲突并解决后。
从 Git 2.35 开始,你可以使用:
git log --remerge-diff
这个选项会基于记录的合并策略重演合并提交,并展示其中引入的实际更改。它在调试合并冲突或者回顾复杂的合并历史时相当实用。
6. git blame --ignore-rev – 忽略噪音式提交
当团队进行大规模的格式化更改后,git blame 可能就失去了参考价值,因为所有行都指向了那个“格式调整提交”,而不再是原作者。
Git 2.23 中引入了 --ignore-rev 选项,用来忽略这类提交:
git blame --ignore-rev 提交哈希
想要让这个忽略持久化,可以在项目中设置一个 ignore-revs 文件:
# 将提交哈希添加进 ignore-revs 文件
echo 提交哈希 >> .git-blame-ignore-revs
# 告诉 Git 使用该文件
git config blame.ignoreRevsFile .git-blame-ignore-revs
这样,你就能更准确地关注有意义的提交者,尤其适用于经常有格式化提交的代码库。
7. git range-diff – 对比并追踪提交区间间的变化
无论是通过 rebase、cherry-pick 还是交互式编辑,对提交历史进行重写的操作都可能比较复杂。当我们做完一次 rebase 后,可能想知道重写后的提交与原始提交具体有什么区别。git range-diff 则能帮我们比较两个提交区间,展示它们之间的演进,并突出每个提交的变化差异:
git range-diff
这个命令可以覆盖在多分支、多阶段的迭代开发场景中,以帮助了解一个功能或 bug 修复在不同分支上的演化过程。
8. git worktree – 同时在多个分支上工作
在同一个工作区频繁切换分支会打断工作流程,尤其是当你需要并行处理多个分支的时候。git worktree 允许你为同一个仓库创建额外的工作区:
# 为某个分支添加一个新的工作区
git worktree add ../feature-branch feature-branch
# 完成后删除该工作区
git worktree remove ../feature-branch
使用 git worktree 你能在不同工作区中同时处理多个分支,而无需来回切换或 stash。你也可以创建临时性的工作区(处于分离 HEAD 状态)来做测试,或者在单独的工作区里执行构建和部署操作。
9. git rebase --update-refs – 保持引用同步
Rebase 操作会用新的提交替换旧的提交,导致一些分支指针或标签仍然引用了被舍弃的旧提交。Git 2.38 引入了 --update-refs 选项来自动处理这种情况:
git rebase --update-refs
在执行此命令时,Git 会确保那些引用了被重写提交的相关分支和标签都与新的历史保持一致,省去了手动更新的繁琐,也能让仓库中的引用保持一致。
如果你还想更细粒度地控制,可以进行以下配置,让 rebase 总是更新指定引用:
git config rebase.updateRefs true
当你在协作或需要管理多个引用时,这项功能将大大简化流程。
10. git commit --fixup 与 git rebase --autosquash – 修正型提交
虽然这并不是新功能(在 Git 1.7.4,就已推出),但 git commit --fixup 常常被忽略。它却是保证提交历史整洁的强大工具。开发功能时,如果你需要修复或改进先前的某个提交,手动修改提交历史并不一定稳定。Git 为此提供了 git commit --fixup 与 git rebase --autosquash:
# 创建一个 fixup commit,目标是特定的提交
git commit --fixup=<提交哈希>
# 在稍后的交互式 rebase 中,自动地把 fixup commit 合并到目标提交
git rebase -i --autosquash <基准分支>
--fixup 会创建一个特殊的提交标记,用于在后续执行带有 --autosquash 的交互式 rebase 时,自动将该提交合并进目标提交。这样,你就能在合并代码前,更加轻松地整理提交历史,并将相关改动归纳到一起,无需手动挪动提交。
结论
文中介绍的这些命令,能帮助你解决日常 Git 使用中可能遇到的实际问题。无论你是在管理 monorepo,大规模操作历史,还是想让仓库持续健康,这些命令都能提供很大的助力。不妨先挑一两个尝试融入自己的工作流,你很可能会发现,在提高工作效率方面,它们比想象中更给力。
如果你喜欢这篇文章,不妨再看看 “15 个每位开发者都应该知道的 Git 命令行技巧”。