felipec / git-remote-hg

Transparent bidirectional bridge between Git and Mercurial for Git
GNU General Public License v2.0
369 stars 87 forks source link

Make writing of marks files atomic #55

Open fingolfin opened 8 years ago

fingolfin commented 8 years ago

Right now, git-remote-hg can die while in the middle of writing the marks files, fatally corrupting the state of git-remote-hg, and potentially forcing the user to make a fresh clone.

Things would be better if the marks files were writing atomically, or if at least the time during which a dieing process would cause issues was minimized. E.g. write the the marks first to new files; then swap old and new files atomically (on systems that support that; on systems that don't, first move the old files away, then move the new files into place, then delete the old files; this way, it is quite easy to recover manually).

felipec commented 8 years ago

Marks are stored in a single line of code.

json.dump(self.dict(), open(self.path, 'w'))

fingolfin commented 8 years ago

Sure. But what is the relevance of that remark?

felipec commented 8 years ago

I doubt very much in reality the process is actually dying in the middle of that single line of code.

fingolfin commented 8 years ago

This kind of bug has been known for decades, and countless people have shared your doubt, and paid for it. In this particular case, it can even be reproducibly triggered within git-remote-hg. Hint: Take a repository with a couple hundred thousands of commits in it to increase the likelihood, and then write a stress test script.

Of course it can also happen with a repo that just contains 5000 commits.

felipec commented 8 years ago

Those are different issues.

fingolfin commented 8 years ago

How is the git-remote-hg script dieing in the middle of that "single line of code", resulting in an invalid / incomplete JSON marks file, a different issue?

felipec commented 8 years ago

It's not happening. Show me an incomplete JSON marks file that a user reported with a recent version of git-remote-hg and Git.