撤销 git update-index --assume-unchanged <file>

667

我已运行以下命令,以忽略监视/跟踪特定的目录/文件:

git update-index --assume-unchanged <file>

我该如何撤销这个操作,以便重新对<file>进行监视/跟踪?


8
请注意,似乎skip-worktree比assume-unchanged更适合您使用,除非git的性能是您的问题。 https://dev59.com/nWYr5IYBdhLWcg3wfaSc - GreenAsJade
11个回答

853
要获取设置为假定未更改的目录/文件的撤消/显示,运行以下命令:
git update-index --no-assume-unchanged <file>

要获取在Unix shell中处于assume-unchanged状态的目录/文件列表,请运行以下命令:
git ls-files -v | grep '^h'

或者在PowerShell中:
git ls-files -v | Select-String -CaseSensitive '^h'

7
你的grep语句还需要些改进,可以使用'^[a-z]'来捕获所有被忽略的文件,因为第一个字母标记可能不是'H'/'h'。从http://git-scm.com/docs/git-ls-files:此选项在每行的开头用以下标记(后跟一个空格)标识文件状态:H::已缓存S::跳过工作树M::未合并R::已删除C::修改/更改K::将被删除?::其他 - Bdoserror
9
另一个有用的技巧是 git ls-files -v|grep '^h'|cut -c3-,它将只给出文件名,不包括前缀的 "h "。 - Retsam
14
如果你记不得哪些文件曾经被标记为“假设未更改(assume-unchanged)”,只需要使用“git update-index --really-refresh”命令即可。这个命令可以直接刷新标记,而无需先使用“git ls-files”命令查找这些文件。请注意,命令的原意不变。 - theDmi
4
值得一提的是,如果您使用了 --skip-worktree,撤销/恢复的过程非常类似:使用 git ls-files -v | grep '^S' 列出文件,然后使用 git update-index --no-skip-worktree <file> 恢复。 - geekley
不要忘记先隐藏您的更改。 - Gerson Diniz

147
如果这是您经常使用的命令,您可能还希望考虑为其创建一个别名。请将以下内容添加到全局的.gitconfig文件中:
[alias]
    hide = update-index --assume-unchanged
    unhide = update-index --no-assume-unchanged

如何设置别名(如果您还不知道):

git config --configLocation alias.aliasName 'command --options'

例子:

git config --global alias.hide 'update-index --assume-unchanged'
git config... etc

将这个保存到你的.gitconfig文件后,你可以运行清理命令。
git hide myfile.ext

或者

git unhide myfile.ext

这篇Git文档非常有帮助。

根据评论,以下别名也很有帮助,可以查找当前正在隐藏的哪些文件

[alias]
    hidden = ! git ls-files -v | grep '^h' | cut -c3-

4
这个别名也很方便:hidden = ! git ls-files -v | grep '^h' | cut -c3-。 (注:该命令用于过滤出被Git忽略的文件,以及以"h"标记隐藏的文件) - seanf

60

为了综合@adardesign、@adswebwork和@AnkitVishwakarma的出色原始答案,以及@Bdoserror、@Retsam、@seanf和@torek的评论,并附加文档链接和简明别名...

基本命令

假定未更改文件重置回到正常状态:

git update-index --no-assume-unchanged <file>

列出所有设为未跟踪的文件:

git ls-files -v | grep '^[a-z]' | cut -c3-

将所有设为未更改的文件重置为正常状态:

git ls-files -v | grep '^[a-z]' | cut -c3- | xargs git update-index --no-assume-unchanged --

注意: 这个命令曾经在其他地方列出,但现在似乎不再重置所有已设为假定未更改的文件(我认为它曾经这样做,并且以前将其列为解决方案):

git update-index --really-refresh

快捷方式

为了使这些常见任务在git中易于执行,为您的用户在.gitconfig中添加/更新以下别名部分(例如在*nix或macOS系统上的~/.gitconfig):

[alias]
    hide = update-index --assume-unchanged
    unhide = update-index --no-assume-unchanged
    unhide-all = ! git ls-files -v | grep '^[a-z]' | cut -c3- | xargs git unhide --
    hidden = ! git ls-files -v | grep '^[a-z]' | cut -c3-

1
对于 git hidden,您可以使用 ! 来实现相同的效果,而无需使用 shell 别名或脚本,就像这样:hidden = ! git ls-files -v | grep '^h' | cut -c3- - seanf
1
“--really-refresh” 不会(或者不再)清除索引文件上的 assume-unchanged 标志。 - torek
1
谢谢,@torek!我确认了您描述的行为,并使用不同的解决方案更新了答案以处理“重置所有”情况。 - Will

46

git update-index 函数有几个选项,你可以按照下面的方式找到:

git update-index --help

在这里,您将找到各种选项-如何处理函数update-index。

[如果您不知道文件名]

git update-index --really-refresh 

[如果您知道文件名]

git update-index --no-assume-unchanged <file>

将使所有被添加到忽略列表中的文件恢复正常。

git update-index --assume-unchanged <file>

git update-index --really-refresh,撤销我所做的所有assume-unchanged操作,感谢提示。 - Sérgio
git update-index --no-assume-unchanged <file> 拯救了我的生命...好吧,我本可以再次同步文件夹,但我确实想要一个针对这个问题的“真正”解决方案。 - Cagatay Ulubay

44

我假设(嘿)你的意思是--assume-unchanged,因为我没有看到任何--assume-changed选项。 --assume-unchanged的反义词是--no-assume-unchanged


23

如果你想撤销所有被标记为assume unchanged的文件,包括任何状态而不仅仅是缓存的(git会用小写字母的字符标记它们),你可以使用以下命令:

git ls-files -v | grep '^[a-z]' | cut -c 3- | tr '\012' '\000' | xargs -0 git update-index --no-assume-unchanged
  1. git ls-files -v 命令会列出所有文件及其状态。
  2. grep '^[a-z]' 命令将过滤文件并选择只保留未更改的文件。
  3. cut -c 3- 命令将删除状态信息,仅保留路径信息,从第三个字符开始剪切到末尾。
  4. tr '\012' '\000' 命令会将换行符(\012)替换为零字符(\000)。
  5. xargs -0 git update-index --no-assume-unchanged 命令将使用零字符分隔的所有路径传递给git update-index --no-assume-unchanged命令以撤消之前的操作。

12

@adardesign 的答案基础上,如果您想一次性将所有添加到 assume-unchanged 列表中的文件重置为 no-assume-unchanged,可以执行以下操作:

git ls-files -v | grep '^h' | sed 's/^..//' | sed 's/\ /\\ /g' | xargs -I FILE git update-index --no-assume-unchanged FILE || true

这只是剥离grep输出的两个字符,即"h ",然后转义任何可能存在于文件名中的空格,最后|| true将防止命令在循环中某些文件出错时过早终止。


5
如果您正在使用Git扩展,则按照以下步骤操作:
  1. 进入提交窗口。
  2. 单击名为“工作目录更改”的下拉菜单。
  3. 选择“显示假定未更改的文件”选项。
  4. 右键单击要取消假定的文件。
  5. 选择“不要假定未更改”。
完成了。

1

没有什么是没有涵盖的。但我想要加上我的两分钱。有时候,我运行一个构建并且它改变了很多文件,然后我想要处理一些事情,所以这个命令真的帮了我很多。

git update-index --assume-unchanged `git status | grep modified | sed 's|modified:||g'| xargs`

希望其他人也会发现它有用。


我认为你会受益于使用.gitignore来忽略你的构建产物。 - Nick
1
我有.gitignore文件,但在我的经验中,有时这并不足够。但我理解你说这话的背景。 - Tyagi Akhilesh

0

对于我来说,Windows上的所有解决方案都不起作用 - 它似乎使用大写字母H而不是小写字母h来表示文件状态,并且grep命令需要额外的插入符号^,因为它也代表行的开头以及否定下一个字符。

Windows解决方案

打开 Git Bash 并切换到相关的顶级目录。 使用 git ls-files -v | grep '^^H' 命令列出所有未缓存的文件。 使用 git ls-files -v | grep '^^H' | cut -c 3- | tr '\012' '\000' | xargs -0 git update-index --no-skip-worktree 命令撤销通过 update-index --skip-worktree 所进行的文件跳过操作。 使用 git ls-files -v | grep '^^H]' | cut -c 3- | tr '\012' '\000' | xargs -0 git update-index --no-assume-unchanged 命令撤销通过 update-index --assume-unchanged 所进行的文件跳过操作。 再次使用 git ls-files -v | grep '^^H' 命令列出所有未缓存的文件,并检查上述命令是否生效 - 此时不应返回任何结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接