Skip to content

Commit 5f6a8a9

Browse files
committed
Use a temp file + rename for atomic changes
We were updating the files in place. This left a small time frame where files may be commited while in the middle of a write. The final, complete file would then be commited soon after, but we would end up with an ugly, partial commit in the history. Using a temporary file then a rename ensure git only see complete files (rename is atomic on POSIX filesystems).
1 parent b59030b commit 5f6a8a9

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

pkg/recorder/recorder.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,22 @@ func (w *Listener) save(file string, data []byte) error {
144144
w.actives[w.relativePath(file)] = true
145145
w.activesLock.Unlock()
146146

147-
err = afero.WriteFile(appFs, file, data, 0600)
147+
tmpf, err := afero.TempFile(appFs, "", "katafygio")
148+
if err != nil {
149+
return fmt.Errorf("failed to create a temporary file: %v", err)
150+
}
148151

152+
_, err = tmpf.Write(data)
149153
if err != nil {
150-
return fmt.Errorf("failed to write to %s on disk: %v", file, err)
154+
return fmt.Errorf("failed to write to %s on disk: %v", tmpf.Name(), err)
155+
}
156+
157+
if err := tmpf.Close(); err != nil {
158+
return fmt.Errorf("failed to close a temporary file: %v", err)
159+
}
160+
161+
if err := appFs.Rename(tmpf.Name(), file); err != nil {
162+
return fmt.Errorf("failed to rename %s to %s: %v", tmpf.Name(), file, err)
151163
}
152164

153165
return nil

0 commit comments

Comments
 (0)