我需要将git repo克隆到现有目录($HOME
中,以管理dotfiles)。我正在进行裸克隆并重新配置它,因为我需要克隆到现有的 unclean 工作目录中。 可行,但我发现git status
尝试在首次使用时运行过滤器。为什么会这样做,我该如何预防呢?
试试这个:
# create a test repo
mkdir test && cd test
git init
echo hello > hello.txt
git add .
git commit -m 1
echo 'hello.txt filter=foo diff=bar' > .gitattributes
git add .
git commit -m 2
# clone it bare and configure it
mkdir ../test2 && cd ../test2
git clone --bare ../test .git
git config core.bare false
git config core.logallrefupdates true
git reset
git checkout .
git config filter.foo.clean foo
git config filter.foo.smudge foo
git config diff.bar.textconv bar
这个borks
$ git status
error: cannot run foo: No such file or directory
error: cannot fork to run external filter 'foo'
error: external filter 'foo' failed
On branch master
nothing to commit, working tree clean
这不是
$ git status
On branch master
nothing to commit, working tree clean
此外,最初快速连续多次执行git status
(即git status; git status; git status)
会导致多次失败。有时。
据我much reading确认,过滤器只应在检入和检出文件时运行。
那么为什么git status
会运行它们?
答案 0 :(得分:3)
过滤器仅在签入/结帐时运行的想法属于white lie。它意味着使过滤器更容易解释。
事实上,当在索引和工作树之间移动文件时(以及在Git的足够现代版本中,在--path=
和{{1}中使用git show
选项请求时,过滤器会运行)还有git cat-file
:其中一些是直接从存储库转换到stdout,或者从stdin转换到存储库)。这大部分相当于签入/结帐时间。但是由于索引的缓存方面,git hash-object
也有特殊的分配。
出于性能原因,Git想要知道工作树中的任何文件是否可能是"脏"关于索引中的版本。 Git假定git status
值stat
(通常具有一秒分辨率, 1 )可用于此目的:如果st_mtime
时间< em> file - 工作树条目 - 早于索引条目中保存的st_mtime
,然后索引条目是最新的,并且是#34;清理&#34;:在应用干净的过滤器等之后,索引中的内容与工作树中的内容相匹配。
如果工作树条目的时间戳比更新保存的索引条目,那么该文件肯定已被修改:索引条目可能不在日期。它没有保证过时,因为工作树文件可能已经以最终没有变化的方式进行了修改。但显然有必要运行清洁过滤器(以及任何CR / LF线结束hackery)。
如果两个时间戳相同,则工作树条目是不确定的。 (Git称之为&#34; racily clean&#34;虽然&#34;非常脏&#34;同样准确。)
在所有这些情况下,st_mtime
将在工作树文件上运行清理过滤器(以及任何输入到Git方向的CR / LF修改)以计算新的哈希。如果新哈希与索引哈希匹配,Git可以并且将更新索引条目以将文件标记为&#34;实际上清理&#34;。现在,下次你做某事时,Git不必运行清洁过滤器。
除非,即在git status
统计字段的分辨率内完成所有操作。在这种情况下,索引条目结束了&#34; racily clean&#34;而Git必须再试一次。这就是你在这里观察到的。
(顺便说一下,st_mtime
运行两个差异:一个从git status
到索引,一个从索引到工作树。它是&#39;第二个差异从索引的缓存方面受益匪浅。索引现在也可以存储有关未缓存的文件和目录的信息!)
1 一些HEAD
调用给出亚秒级精度,但由于各种原因,索引/缓存条目通常只存储1秒分辨率时间戳。
有关此问题的更多内容,请参阅the racy-git.txt
file in the technical documentation。