Build1 distinct publisher3 min readPublished
Autostash saves your dirty tree and then reapplies it on top of what the pull fetched. When the hunks are disjoint the merge succeeds, the fossil line gets the current second as its mtime, and no ref survives to trace it by.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
Follow any of these and your For You feed starts watching them — no settings page required.
build
Given one full stop as input, a coding agent mined the shared run record for work1 distinct publisher
build
Five coding agents on one repo is a staffing problem, and worktrees only fix the filesystem1 distinct publisher
build
Claude Code walks the whole process table to inherit one shell's environment1 distinct publisher
build
Parallel coding agents on Windows break at the home directory, not the launcher1 distinct publisher
A stash is a diff, and a diff carries no age [7]. That is the whole of it. Autostash saves the dirty tree, moves HEAD to the fetched upstream tip, then replays the saved diff over the files it just wrote [7]. If your stale hunks and upstream's hunks sit in different regions of the file, the three-way merge succeeds and nothing in the result marks which lines came from the fetch and which came from your tree [7]. In the author's reproducer, `tool.sh` ends up with the fetched fix on line one and the working copy's three-day-old footer at the bottom, while `git show HEAD:tool.sh` still holds the committed line [4][5].
The timestamp follows from the same mechanism. The replay is a write, and the write happens now, so `stat` and `date -u` agree to the second [6]. Arithmetic on the two facts the post supplies: the content is three days old, the mtime is the current second, so the file's timestamp understates the age of that line by roughly 72 hours [13]. Ilya Mozerov, writing on dev.to, notes that his earlier argument was that mtime can lie; this post names a binary in everyone's `$PATH` that makes it lie as a convenience feature [14].
Now the channel a script actually reads. The clean replay exits zero [3]. The conflicted replay prints "Applying autostash resulted in conflicts", leaves `UU tool.sh` and three lines of whitespace-and-marker complaints from `git diff --check`, and also exits zero [8]. So the exit status distinguishes neither case from a healthy pull [12], which is why `git pull && make` walks straight through both, as the author puts it [10]. Git does say so, but only in a line of text on stdout; the exit status carries none of it.
Reaching this failure mode takes several conditions lining up at once: `pull.rebase` and `rebase.autoStash` both set [1], upstream ahead of you, a dirty tree at the moment you pull, and hunks that do not collide [7]. A team that only pulls clean never fires the path. Treat the reproducer as a claim about a config pair, not about git being broken.
For me, the forensics settle it. In the conflict case git says your changes are safe in the stash, and they are [8]. In the clean case it drops the stash: `git stash list` is empty, there is no stash reflog, and the only remaining record is a dangling commit awaiting `git gc` [9]. So in my repos autostash stays off and a dirty pull is allowed to fail. If you keep it on, the cheap mitigation is a wrapper that captures the hash git prints on the way in, from `Created autostash: 627da2a` [3], and logs it before it becomes unreachable [9].
Ranked by verification strength, evidence, and original report placement.
The post's setup is two git config lines: `git config pull.rebase true` and `git config rebase.autoStash true`, described as the sort of thing you set once and never look at again.
The author ran the demonstrated `git pull` on git 2.43.0.
The pull output shows `d568744..670a133 main -> origin/main`, `Created autostash: 627da2a`, `Fast-forward`, `tool.sh | 2 +-`, `Applied autostash.`, and `echo $?` returns 0; the author notes nothing in that output is a warning.
After the pull, `cat tool.sh` shows `header v2 FIXED / body v1 / footer ANCIENT`, while `git show HEAD:tool.sh` shows `header v2 FIXED / body v1 / footer v1`.
Upstream had a fix in it, and the author's working tree carried an unrelated line that was three days old.
`stat -c '%y' tool.sh` reported 2026-08-30 02:04:12.307739896 +0000 while `date -u` reported 2026-08-30T02:04:12Z, the same second.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 29, 2026
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Reproducible, but single-transcript
The best thing in this story is that you do not have to believe it: dev.to's post pins the git version, gives the two config lines, and hands over a self-contained script that reproduces the silent replay in about a second. That is unusually falsifiable for a developer blog post. The weaker half is the part no script settles for you — the conflicted-pull transcript, with its zero exit status and `UU tool.sh`, and the dangling-commit forensics both come from one machine's terminal, unrepeated by anyone else.
Nothing counted
Nobody here counts anything: no share of repositories running pull.rebase with rebase.autoStash, no pipelines audited, no incident beyond the author's lost day. The one deployment on record is his own commit-landing automation, described rather than measured. How much of the world's build estate actually sits in this configuration is precisely the number this reporting does not have, and we would rather leave the field blank than promote one developer's laptop into a population.
Demonstrations land, extrapolation runs ahead
Slightly overstated, and it is easy to see where. 'Every git pull && make in every deploy script on earth' is a claim about the world's CI estate that nobody measured, and 'makes it lie, on purpose' dresses a documented convenience feature — which does print `Applied autostash.` — in intent it does not have. Discount the sweep and the villainy; keep the mechanism, because the disjoint-hunk replay, the current-second mtime and the zero exit code are shown rather than argued.
No vendor, one thesis to feed
Nothing is being sold. There is no company, product, funding or benchmark in the frame; the pull ran on the author's own machine and cost him a day. The only pressure worth naming is authorial: the post is explicitly a sequel to his earlier 'mtime is not a claim' argument, and a culprit sitting in everybody's $PATH is a very convenient second act — which is exactly where the rhetorical edges appear.
Verifiable core, unverified tail
One publisher, one machine, one git version — offset by a reproducer that closes most of the gap. We land mid-range because the findings split cleanly: anyone can confirm the silent replay and the timestamp stamped at the current second, while the conflict-case exit status and the stash vanishing after collection stand on the author's word alone. A second run on a different git build would move this figure fast, in either direction.