微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Git 的 `.gitattributes` 过滤器不更新工作树中的内容

如何解决Git 的 `.gitattributes` 过滤器不更新工作树中的内容

我想使用 .gitattributes 过滤器来更新 git add 上的文件(实际上,提交之前的任何内容都可以)。

然而,尽管运行了过滤器,但工作树中的内容保持不变。

我做了一个最小的回购作为展示:

foo.txt

Foo
<start>
<stop>
Bar

update-toc

#!/usr/bin/env python3

import re
import sys

def parse(lines):
    start = -1
    stop = -1
    for i,line in enumerate(lines):
        if re.match('<start>',line):
            start = i
            continue
        if re.match('<stop>',line):
            stop = i
            continue
    return start,stop

print('STARTING FILTER',file=sys.stderr)
lines = sys.stdin.readlines()
start,stop = parse(lines)
if start != -1 and stop != -1:
    new_lines = lines[:start + 1] + ['baz\n'] + lines[stop:]
else:
    new_lines = lines
sys.stdout.write(''.join(new_lines))
print('ENDING FILTER',file=sys.stderr)
sys.stderr.write(''.join(new_lines))

.gitattributes

*.txt   filter=update-toc

.git/config

[filter "update-toc"]
        smudge = ./update-toc
        clean = ./update-toc
        required

在这个 repo 上,如果我运行以下命令,我可以看到过滤器成功运行,但内容本身没有更新:

$ git add --renormalize foo.txt
STARTING FILTER
ENDING FILTER
Foo
<start>
baz
<stop>
Bar

$ cat foo.txt
Foo
<start>
<stop>
Bar

除了我自己的修改之外,各种编辑和提交不会改变 foo.txt

如果我删除 foo.txt 然后检查它 (git checkout) 然后我将检索过滤后的版本。

$ rm foo.txt
$ git checkout foo.txt
$ cat foo.txt
Foo
<start>
baz
<stop>
Bar

有没有办法修改工作树内容自动检查它(也许将过滤器与 Git 钩子结合起来)?

解决方法

无论好坏,这都是一个干净的过滤器意味着的工作方式。它永远不会改变工作树副本中的内容:它仅适用于 Git 将在其压缩器中看到的字节流。1

作为phd suggested in a comment,更新工作树副本的可靠方法是单独进行。理论上,如果你能得到工作树对象的名称——你可以使用长时间运行的协议——你可以先过滤文件,然后就地更新它(可能是异步的),但这会引入很多潜在的竞争,并且作为 the documentation notes,该文件甚至可能不存在于该路径名中(对于干净过滤器通常不会出现这种情况,但可能存在一些不明显的极端情况)。

(此时,即使没有污迹过滤器,从索引中检查文件也能正常工作,因为文件的 index 副本包含添加的行。)


1压缩器进行 zlib 压缩以生成新的内部 blob 对象;它还同时计算哈希 ID。生成的散列 ID 要么是某个现有对象的散列 ID(在这种情况下,新 blob 是一个重复的对象,为了支持现有对象而被丢弃),要么是一个新对象(在这种情况下,新 blob 被添加到存储库中)对象数据库)。新 blob 的哈希 ID 现在有效并替换索引中的旧哈希 ID(如果文件之前在索引中),或者成为索引中新条目的哈希 ID(如果文件是索引中的新文件)现在。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。