10

我喜欢直接修改配置文件(如 .gitignore 和 .git/config),而不是记住任意命令,但我不知道 Git 将传递给“git update-index --assume-unchanged 文件”的文件引用存储在哪里”。

如果你知道,请告诉!

4

2 回答 2

4

它说明了命令中的位置 - git update-index

因此,您不能真正编辑索引,因为它不是文本文件。

此外,要详细了解git update-index --assume-unchanged命令存储的内容,请参阅Using “assume unchanged” bit 手册中的部分

于 2011-08-18T22:47:10.537 回答
3

正如其他人所说,它存储在索引中,该索引位于.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)从 更改0080是我们的标志,缓存条目标志的第一位。
  • 0x4C从到的 20 个字节0x5F。这是意料之中的,因为这是整个索引的 SHA-1。

尽管我也认为索引条目的 SHA-1 以字节为单位从0x340x47不考虑标志,因为它在两个索引之间没有改变。这可能就是为什么将标志放在 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_VALIDcache.h

#define CE_STAGEMASK (0x3000)
#define CE_EXTENDED (0x4000)
#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12

所以我们得出结论,它是整数 ( 0x8000) 的第一位,就在 旁边CE_EXTENDED,这与我之前的实验一致。

于 2015-02-22T11:05:08.573 回答