isomorphic-git / isomorphic-git/isomorphic-git

Repository in inconsistent state after git fetch

Open
#1,299 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
8.4k
Forks
491
Avg merge
2h 53m
Merged PRs (30d)
7

Description

When using isomorphic-git with lightning-fs in the browser, I occasionally find the repository in an inconsistent state where you cannot read the commit of remote HEAD after `git fetch`:

```js
let oid = await git.resolveRef({ fs, dir, ref: 'refs/remotes/origin/main' })

// Throws "Uncaught NotFoundError: Could not find ${oid}."
await git.readCommit({ fs, dir, oid })
```

I suspect the cause of this problem is that the `fetch` implementation is non-atomic. Quoting [Using IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#warning_about_browser_shutdown) on MDN:

> Since the user can exit the browser at any time, this means that you cannot rely upon any
> particular transaction to complete, and on older browsers, you don't even get told when they don't
> complete. ...you should take care to always leave your database in a consistent state at the end
> of every transaction.

In the `_fetch` function, the remote refs are updated before the packfile is written. As lightning-fs writes the cache to IndexedDB with a debounce of 500ms, if the user closes the tab between the persistence of remote refs and packfile, the remote HEAD will point to a nonexistent object.

This can be reproduced by adding `await new Promise(r => setTimeout(r, 1000));` before [this line](https://github.com/isomorphic-git/isomorphic-git/blob/v1.8.0/src/commands/fetch.js#L345), and closing the tab during the sleeping.

A possible fix might be expose the [`DefaultBackend._saveSuperblock`](https://github.com/isomorphic-git/lightning-fs/blob/v4.4.1/src/DefaultBackend.js#L79) method and allow the user to manually persist the FS after fetching, instead of relying on saving it regularly.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.