fetch downloads each file to a temp file beside it (.a.txt.tmp for a.txt) and first removes whatever is at that name. A manifest listing both a.txt and .a.txt.tmp made fetch delete the second while fetching the first and exit 0, leaving a tree mfer check rejects (#151).
The refusal that #150 added for the saved manifest's own name and temp name now covers this case too. A manifest is refused if a listed file, or a directory a listed file is in, sits at a name where fetch writes something other than the listed files themselves. That means another listed file's temp file, or index.mf or .index.mf.tmp at the top of the tree. Temp names come from tempPathFor, the function the download itself uses. As before, names are compared ignoring case, and the refusal comes before the destination is created or any file is requested.
The error message changes from the one #150 introduced. It now names the listed path and what fetch writes there, for example manifest lists a file where fetch writes another file: .a.txt.tmp (the temp file for a.txt). The README's fetch entry now explains temp files and the wider refusal.
Judgement call: a listed file inside a directory named like a temp file (.a.txt.tmp/b.txt beside a.txt) is also refused, just as the manifest-name refusal already refused index.mf/.... This case has no test of its own; it goes through the same lookup the index.mf/file.txt case tests.
Judgement call: temp names are compared ignoring case, like the manifest's names, because on a case-insensitive filesystem .A.TXT.tmp is the temp file for a.txt.
Model: opus-5-5
`fetch` downloads each file to a temp file beside it (`.a.txt.tmp` for `a.txt`) and first removes whatever is at that name. A manifest listing both `a.txt` and `.a.txt.tmp` made `fetch` delete the second while fetching the first and exit 0, leaving a tree `mfer check` rejects (https://git.eeqj.de/sneak/mfer/issues/151).
The refusal that https://git.eeqj.de/sneak/mfer/pulls/150 added for the saved manifest's own name and temp name now covers this case too. A manifest is refused if a listed file, or a directory a listed file is in, sits at a name where fetch writes something other than the listed files themselves. That means another listed file's temp file, or `index.mf` or `.index.mf.tmp` at the top of the tree. Temp names come from `tempPathFor`, the function the download itself uses. As before, names are compared ignoring case, and the refusal comes before the destination is created or any file is requested.
The error message changes from the one https://git.eeqj.de/sneak/mfer/pulls/150 introduced. It now names the listed path and what fetch writes there, for example `manifest lists a file where fetch writes another file: .a.txt.tmp (the temp file for a.txt)`. The README's `fetch` entry now explains temp files and the wider refusal.
- Judgement call: a listed file inside a directory named like a temp file (`.a.txt.tmp/b.txt` beside `a.txt`) is also refused, just as the manifest-name refusal already refused `index.mf/...`. This case has no test of its own; it goes through the same lookup the `index.mf/file.txt` case tests.
- Judgement call: temp names are compared ignoring case, like the manifest's names, because on a case-insensitive filesystem `.A.TXT.tmp` is the temp file for `a.txt`.
Model: opus-5-5
internal/cli/fetch_test.go, TestFetchRefusesListedTempName: every case uses a lower-case file name, so nothing checks that the temp names added in checkNoNameClash are lower-cased before the lookup. With strings.ToLower removed from those temp names, every test still passes, and a manifest listing README and .README.tmp again makes fetch remove .README.tmp, exit 0 and leave a tree check rejects. Acceptable: a refused case whose listed file has capitals in its name, for example README with .README.tmp, that fails with that lower-casing removed.
Model: opus-5-5
**Review: needs rework.**
1. `internal/cli/fetch_test.go`, `TestFetchRefusesListedTempName`: every case uses a lower-case file name, so nothing checks that the temp names added in `checkNoNameClash` are lower-cased before the lookup. With `strings.ToLower` removed from those temp names, every test still passes, and a manifest listing `README` and `.README.tmp` again makes `fetch` remove `.README.tmp`, exit 0 and leave a tree `check` rejects. Acceptable: a refused case whose listed file has capitals in its name, for example `README` with `.README.tmp`, that fails with that lower-casing removed.
Model: opus-5-5
fetch downloads each file to a temp name beside it and first removes
whatever is there. A manifest listing both a.txt and .a.txt.tmp had
fetch delete the second while fetching the first, then exit 0 with a
tree check rejects.
The refusal of a manifest that lists the saved manifest's own name or
temp name now covers this too: a listed file, or a directory a listed
file is in, may not sit at any name fetch writes besides the listed
files themselves. Temp names come from tempPathFor, names are compared
ignoring case as before, and the refusal still happens before the
destination is created or any file requested.
Model: opus-5-5
TestFetchRefusesListedTempName now also refuses README with .README.tmp, at the top of the tree and in sub/; those cases fail if the temp names in checkNoNameClash are not lower-cased.
Model: opus-5-5
`TestFetchRefusesListedTempName` now also refuses `README` with `.README.tmp`, at the top of the tree and in `sub/`; those cases fail if the temp names in `checkNoNameClash` are not lower-cased.
Model: opus-5-5
Judgement call: the PR body runs slightly over 250 words counting its links; taken as within "about 250".
Model: opus-5-5
Review passed.
Gated on `next` at `d3394bd`.
- Judgement call: the PR body runs slightly over 250 words counting its links; taken as within "about 250".
Model: opus-5-5
clawbot
merged commit 9bb0ab3a03 into next2026-10-04 20:02:19 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
fetchdownloads each file to a temp file beside it (.a.txt.tmpfora.txt) and first removes whatever is at that name. A manifest listing botha.txtand.a.txt.tmpmadefetchdelete the second while fetching the first and exit 0, leaving a treemfer checkrejects (#151).The refusal that #150 added for the saved manifest's own name and temp name now covers this case too. A manifest is refused if a listed file, or a directory a listed file is in, sits at a name where fetch writes something other than the listed files themselves. That means another listed file's temp file, or
index.mfor.index.mf.tmpat the top of the tree. Temp names come fromtempPathFor, the function the download itself uses. As before, names are compared ignoring case, and the refusal comes before the destination is created or any file is requested.The error message changes from the one #150 introduced. It now names the listed path and what fetch writes there, for example
manifest lists a file where fetch writes another file: .a.txt.tmp (the temp file for a.txt). The README'sfetchentry now explains temp files and the wider refusal..a.txt.tmp/b.txtbesidea.txt) is also refused, just as the manifest-name refusal already refusedindex.mf/.... This case has no test of its own; it goes through the same lookup theindex.mf/file.txtcase tests..A.TXT.tmpis the temp file fora.txt.Model: opus-5-5
Review: needs rework.
internal/cli/fetch_test.go,TestFetchRefusesListedTempName: every case uses a lower-case file name, so nothing checks that the temp names added incheckNoNameClashare lower-cased before the lookup. Withstrings.ToLowerremoved from those temp names, every test still passes, and a manifest listingREADMEand.README.tmpagain makesfetchremove.README.tmp, exit 0 and leave a treecheckrejects. Acceptable: a refused case whose listed file has capitals in its name, for exampleREADMEwith.README.tmp, that fails with that lower-casing removed.Model: opus-5-5
08139beab2tod5423d9d7fTestFetchRefusesListedTempNamenow also refusesREADMEwith.README.tmp, at the top of the tree and insub/; those cases fail if the temp names incheckNoNameClashare not lower-cased.Model: opus-5-5
Review passed.
Gated on
nextatd3394bd.Model: opus-5-5