IPFS MFS snapshots

Hi,
I have a project where I store files using the IPFS MFS. This project is kind of a version controlling system where I store files and update them whenever it changes. If a file changes I have to keep track of the change and the previous state of the file. Since adding the same file even after a minor change is inefficient, I thought of getting a snapshot of the old file and pointing it to the current location.

I found the documentation for file snapshotting (https://docs.ipfs.io/guides/examples/snapshots/) but it lacks details and unclear on how to get a snapshot of a file.

Is there any better workaround or a solution for this?
Suggestions and help appreciated…

Thanks =).

I think the point that example is making is just that if you have the blocks for a given CID in your repo, you can access it even if you later ‘change’ that file.

Sidestepping the use of Fuse in the example:

const toBuffer = require('it-to-buffer')

// write v1 of a file
await ipfs.files.write('/file.txt', 'v1 file content', {
  create: true
})

// get the CID of v1 of the file
const { cid: v1Cid } = await ipfs.files.stat('/file.txt')

// overwrite the file with v2
await ipfs.files.write('/file.txt', 'v2 file content', {
  offset: 0,
  truncate: true
})

// get the CID of v2 of the file
const { cid: v2Cid } = await ipfs.files.stat('/file.txt')

// read the content of both files from the repo via the CID
const v1Content = await toBuffer(ipfs.files.read(`/ipfs/${v1Cid}`))
const v2Content = await toBuffer(ipfs.files.read(`/ipfs/${v2Cid}`))

// read the current contents of the file by mfs path
const fileContent = await all(ipfs.files.read('/file.txt'))

// what do we have?
console.info(v1Content.toString()) // "v1 file content"
console.info(v2Content.toString()) // "v2 file content"
console.info(fileContent.toString()) // "v2 file content"

There is a caveat here that all blocks under your MFS root are protected from garbage collection (assuming you’re running with it enabled) - if you write the same path twice, you’ll need to manually ipfs.pin.add the CID of the original version, v1Cid above.

Since adding the same file even after a minor change is inefficient, I thought of getting a snapshot of the old file and pointing it to the current location.

If you know the byte offsets in the file that have changed, you can use the offset and length arguments to ipfs.files.write to not have to re-import the whole file.

1 Like

Hi @achingbrain thanks for getting back…Your solution looks perfect for my scenario… I’ll try this and see whether it works with my project.
Thanks again =).