Skip to content

Commit

Permalink
Use a temp file + rename for atomic changes
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
bpineau committed Apr 20, 2018
1 parent b59030b commit 5f6a8a9
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions pkg/recorder/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,22 @@ func (w *Listener) save(file string, data []byte) error {
w.actives[w.relativePath(file)] = true
w.activesLock.Unlock()

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

_, err = tmpf.Write(data)
if err != nil {
return fmt.Errorf("failed to write to %s on disk: %v", file, err)
return fmt.Errorf("failed to write to %s on disk: %v", tmpf.Name(), err)
}

if err := tmpf.Close(); err != nil {
return fmt.Errorf("failed to close a temporary file: %v", err)
}

if err := appFs.Rename(tmpf.Name(), file); err != nil {
return fmt.Errorf("failed to rename %s to %s: %v", tmpf.Name(), file, err)
}

return nil
Expand Down

0 comments on commit 5f6a8a9

Please sign in to comment.