3 subject="""comment 1"""
4 date="2019-12-26T16:56:38Z"
6 The title makes it sound like a work tree file gets replaced with a
7 dangling pointer file, which is not the case. A worktree file that was
8 not annexed is is being added to the annex, if you choose to commit that
11 For whatever reason, git becomes confused about whether this file is
12 modified. I seem to recall that git distrusts information it recorded in
13 its own index if the mtime of the index file is too close to the
14 mtime recorded inside it, or something like that. (Likely as a
15 workaround for mtime granularity issues with various filesystems.) Whatever
16 the reason, git-annex is not involved in it; it will happen sometimes even
17 when git-annex has not initialized the repo and is not being used.
19 It's not normally a problem that git gets confused or distrusts its
20 index or whatever, since all it does is stat the file, or
21 feed it through the clean filter again, and if the file is not
22 modified, nothing changes.
24 Why does the clean filter decide to add the file to annex in this case?
26 Well, because this is all happening inside this:
28 git -c annex.largefiles=anything annex add -- file-annex
30 And there you've told it to add all files to the annex with
31 annex.largefiles=anything. So it does.
33 To complete the description of what happens:
34 `git-annex add` runs `git add` on the `file-annex` symlink it's adding.
35 `git add file-annex`, for whatever reason, decides to run the clean filter on
37 The annex.largefiles=anything gets inherited through this chain of calls.
39 While the resulting "change" does not get staged by `git add`
40 (it was never asked to operate on that file), the clean filter
41 duly ingests the content into the annex, and remembers its inode.
42 So when the clean filter later gets run by `git status`, it sees an inode
43 it knows it saw before, and assumes it should remain annexed.
44 (This is why the commit that checks for known inodes was fingered by the
49 Note that, you can accomplish the same thing without setting
50 annex.largefiles, assuming a current version of git-annex:
53 git annex add file-annex
55 I think the only reason for setting annex.largefiles in either of the two
56 places you did is if there's a default value that you want to
61 Also, just touching file-git before the annex.largefiles=anything
62 operation causes the same problem, again git-annex add runs git add
63 file-annex, which runs the clean filter on file-git, which this time
64 is legitimately modified.
68 Possible ways to improve this short of improving git's behavior:
70 `git annex` could set annex.gitaddtoannex=false when it runs `git add`.
71 Since git-annex never relies on `git add` adding files to the annex,
72 that seems entirely safe to always do (perhaps even when running all git
73 commands aside from git-annex commands of course). But, that would
74 not help with a variant where rather than `git-annex add`,
77 git -c annex.largefiles=anything add file-annex
79 The clean filter could delay long enough that git stops distrusting
80 its index based on timestamps. A 1 second sleep if the file's mtime
81 is too close to the current time works; I prototyped a patch doing that.
82 But, that does not deal with the case
83 mentioned above where file-git gets touched or legitimately modified.
85 The clean filter could check if the file is already
86 in the index but is not annexed, and avoid converting it to annexed.
87 But that would prevent legitimate conversions from git to annexed
88 as well, which rely on the same kind of use of annex.largefiles.
90 Temporary overrides of annex.largefiles could be ignored by the clean
91 filter. Same problem as previous.
93 So, I think that fixing this will involve adding a new interface for
94 converting between git and annexed files that does not involve
95 -c annex.largefiles. That plus having the clean filter check for
96 non-annexed files seems like the best approach.