我喜欢直接修改配置文件(如 .gitignore 和 .git/config),而不是记住任意命令,但我不知道 Git 将传递给“git update-index --assume-unchanged 文件”的文件引用存储在哪里”。
如果你知道,请告诉!
它说明了命令中的位置 - git update-index
因此,您不能真正编辑索引,因为它不是文本文件。
此外,要详细了解git update-index --assume-unchanged
命令存储的内容,请参阅Using “assume unchanged” bit
手册中的部分
正如其他人所说,它存储在索引中,该索引位于.git/index
.
经过一番侦探工作,我发现它位于:假设每个索引条目的有效位。
因此,在了解以下内容之前,您应该先了解索引的全局格式,正如我在另一个答案中所解释的那样。
接下来,我将解释我如何验证“假设有效”位是罪魁祸首:
时间到hd
了。
设置:
git init
echo a > b
git add b
然后:
hd .git/index
给出:
00000000 44 49 52 43 00 00 00 02 00 00 00 01 54 e9 b6 f3 |DIRC........T...|
00000010 2d 4f e1 2f 54 e9 b6 f3 2d 4f e1 2f 00 00 08 05 |-O./T...-O./....|
00000020 00 de 32 ff 00 00 81 a4 00 00 03 e8 00 00 03 e8 |..2.............|
00000030 00 00 00 00 e6 9d e2 9b b2 d1 d6 43 4b 8b 29 ae |...........CK.).|
00000040 77 5a d8 c2 e4 8c 53 91 00 01 62 00 c9 a2 4b c1 |wZ....S...b...K.|
00000050 23 00 1e 32 53 3c 51 5d d5 cb 1a b4 43 18 ad 8c |#..2S<Q]....C...|
00000060
现在:
git update-index --assume-unchanged b
hd .git/index
给出:
00000000 44 49 52 43 00 00 00 02 00 00 00 01 54 e9 b6 f3 |DIRC........T...|
00000010 2d 4f e1 2f 54 e9 b6 f3 2d 4f e1 2f 00 00 08 05 |-O./T...-O./....|
00000020 00 de 32 ff 00 00 81 a4 00 00 03 e8 00 00 03 e8 |..2.............|
00000030 00 00 00 00 e6 9d e2 9b b2 d1 d6 43 4b 8b 29 ae |...........CK.).|
00000040 77 5a d8 c2 e4 8c 53 91 80 01 62 00 17 08 a8 58 |wZ....S...b....X|
00000050 f7 c5 b3 e1 7d 47 ac a2 88 d9 66 c7 5c 2f 74 d7 |....}G....f.\/t.|
00000060
通过比较两个索引,并查看索引的全局结构,可以看出唯一的区别是:
0x48
(第 9 行40
)从 更改00
为80
。那是我们的标志,缓存条目标志的第一位。0x4C
从到的 20 个字节0x5F
。这是意料之中的,因为这是整个索引的 SHA-1。尽管我也认为索引条目的 SHA-1 以字节为单位从0x34
到0x47
不考虑标志,因为它在两个索引之间没有改变。这可能就是为什么将标志放在 SHA 之后的原因,它只考虑它之前的内容。
现在让我们看看这是否与 Git 2.3 的源代码一致。
先看update-index的来源,grep assume-unchanged
。
这导致以下行:
{OPTION_SET_INT, 0, "assume-unchanged", &mark_valid_only, NULL,
N_("mark files as \"not changing\""),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
{OPTION_SET_INT, 0, "no-assume-unchanged", &mark_valid_only, NULL,
N_("clear assumed-unchanged bit"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
所以值存储在mark_valid_only
. grep 一下,发现它只用在一个地方:
if (mark_valid_only) {
if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG))
die("Unable to mark file %s", path);
return;
}
CE
表示缓存条目。
通过快速检查mark_ce_flags,我们看到:
if (mark)
active_cache[pos]->ce_flags |= flag;
else
active_cache[pos]->ce_flags &= ~flag;
所以该函数基本上设置或取消设置CE_VALID
位,取决于mark_valid_only
,这是一个三态:
--assume-unchanged
--no-assume-unchanged
0
选项的默认值设置在{OPTION_SET_INT, 0
接下来,通过在 下 grepping builtin/
,我们看到没有其他地方设置 的值CE_VALID
,因此--assume-unchanged
必须是唯一设置它的命令。
但是,该标志在源代码的许多地方都使用了,这应该是可以预料的,因为它有很多副作用,并且每次都使用它,例如:
ce->ce_flags & CE_VALID
所以我们得出结论,它是ce_flags
领域的一部分struct cache_entry
。
指定索引是cache.h
因为它的功能之一是作为缓存以更快地创建提交。
通过查看下线和周围线的定义,我们有CE_VALID
:cache.h
#define CE_STAGEMASK (0x3000)
#define CE_EXTENDED (0x4000)
#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12
所以我们得出结论,它是整数 ( 0x8000
) 的第一位,就在 旁边CE_EXTENDED
,这与我之前的实验一致。