1. 概述

在 Git 中,有时我们希望本地对某些已追踪文件的修改不被提交,比如配置文件中本地的数据库连接地址。此时,我们可能会想到使用 --assume-unchanged--skip-worktree 这两个选项。

这两个选项虽然看起来功能相似,但其背后的行为逻辑和使用场景却大不相同。本文将从实际使用角度出发,分析它们的异同、优先级以及在分支切换时的表现。


2. --assume-unchanged 是做什么的?

--assume-unchanged 的作用是告诉 Git:假设这个文件在工作目录中没有被修改。因此,即使你修改了这个文件,Git 也不会把它标记为“已修改”,也就不会出现在暂存区中。

使用方式如下:

$ git update-index --assume-unchanged assumeunchanged.txt

可以通过 git ls-files -v 来验证文件状态:

$ git ls-files -v
h assumeunchanged.txt

这里的 h 表示该文件被标记为 assume-unchanged

⚠️ 注意:这个选项并不是为了忽略已追踪文件的改动。它的设计初衷是用于优化性能,特别是在文件系统较慢的情况下,Git 会跳过对这些文件的修改检测,从而节省资源。

如果文件在远程被修改并被拉取到本地,那么这个标记会被自动清除。取消标记的方式如下:

$ git update-index --no-assume-unchanged assumeunchanged.txt

3. --skip-worktree 是做什么的?

--skip-worktree 的作用是:忽略本地对该文件的任何未提交修改。Git 会始终使用暂存区中的版本,而忽略工作目录中的内容。

使用方式如下:

$ git update-index --skip-worktree skipworktree.txt

验证文件状态:

$ git ls-files -v
S skipworktree.txt

这里的 S 表示该文件被标记为 skip-worktree

✅ 使用场景:当你希望保留本地的修改(比如本地配置),但又不想这些修改被提交到远程仓库时,这个选项非常有用。

--assume-unchanged 类似,如果文件在远程被修改并被拉取到本地,该标记也会被自动清除。取消标记的方法如下:

$ git update-index --no-skip-worktree skipworktree.txt

4. 两者的区别

4.1 分支切换行为

  • **--skip-worktree**:在切换分支时不会报错。
  • **--assume-unchanged**:在切换分支时会报错:
$ git checkout another-branch
error: Your local changes to the following files would be overwritten by checkout:
        assumeunchanged.txt
Please commit your changes or stash them before you switch branches.
Aborting

解决方法是先取消标记:

$ git update-index --no-assume-unchanged assumeunchanged.txt
$ git checkout another-branch
Switched to branch 'another-branch'

4.2 优先级

当一个文件同时设置了 --assume-unchanged--skip-worktree 时,**--skip-worktree 会优先生效**。

例如:

$ git update-index --assume-unchanged --skip-worktree worktree-assumeunchanged.txt

查看状态:

$ git ls-files -v
S worktree-assumeunchanged.txt

可以看到,标记为 S,说明 skip-worktree 生效。


5. 总结

特性 --assume-unchanged --skip-worktree
目的 优化性能,跳过文件修改检测 忽略本地未提交的修改
是否真正忽略修改 ❌(只是假设未修改)
分支切换是否报错
优先级
文件被远程更新后是否保留标记

✅ 推荐使用建议:

  • 如果你只是想优化性能(比如文件系统慢),使用 --assume-unchanged
  • 如果你希望保留本地修改而不提交,使用 --skip-worktree
  • 不要滥用这两个选项来“忽略”你不想提交的改动,这可能会在团队协作中埋下隐患。

作者:[email protected]
原文链接:Difference Between assume-unchanged and skip-worktree in Git
参考时间:2023-06-01


原始标题:Difference Between assume-unchanged and skip-worktree in Git