-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vault Mutation and Reading #335
Comments
From prototyping I've discovered some things. CLICK ME
dirMeta = {
fs: fs,
dir: dir,
}
commitMeta = {
...dirMeta,
author: {
name: 'Mr. Test',
email: '[email protected]',
},
message: 'hello there!',
};
})
const shortLog = async (stuff) => {
const log = await git.log({
...dirMeta,
...stuff,
});
return log.map(entry => {
return `${entry.commit.message}: ${entry.oid}`
});
}
async function quickCommit(message: string, data: string, ref?: string) {
await fs.promises.writeFile(file, data)
await git.commit({
...commitMeta,
message,
ref,
});
}
async function quickRename(oldref: string, ref: string, override?) {
await git.renameBranch({
...dirMeta,
checkout: true,
oldref,
ref,
...override
})
} Normal committingDuring normal committing where we're appending to the linear history we can maintain the proper // We commit by doing
await git.commit({
...commitMeta,
message: 'test commit',
}); Not providing the ref ensures that both the head and branch are updated. here is another example await git.init({
...dirMeta,
defaultBranch: 'main',
});
await quickCommit('A', 'one');
// {[A]}
await quickCommit('B', 'two');
// A -> {[B]}
const log = await shortLog({});
// [
// 'B\n: b3850ed0d3f13cbd06c403531b24b2c78303d106',
// 'A\n: 40dbe0c4a03c8adbc9ae562fc6646f741cc19f91'
// ]
console.log(await git.currentBranch(dirMeta));
// main branching from detached head stateIf we make use of branches then branching from a detached head can be pretty simple. We can create a temp branch called CLICK ME
// main branch: []
// temp branch: ()
// HEAD: {}
await git.init({
...dirMeta,
defaultBranch: 'main'
});
await quickCommit('S', 'one');
// {[S]}
const ref = (await git.log(dirMeta)).pop()
await quickCommit('A', 'two');
// S => {[A]}
console.log('head', await shortLog({}));
// head [
// 'A\n: b13c65fdc1e600802106822d111cdc2998eab0ef',
// 'S\n: 95c49e1126dafd347a51bc20d1af845d4f123210' <- saved ref here
// ]
console.log(await git.currentBranch(dirMeta));
// main
console.log(await git.listBranches(dirMeta));
// ['main']
// checkout previous commit
await git.checkout({
...dirMeta,
ref: ref!.oid,
})
// {S} -> [A]
// creating a temp branch
console.log('head', await shortLog({}));
// head [ 'S\n: 95c49e1126dafd347a51bc20d1af845d4f123210' ]
console.log(await git.currentBranch(dirMeta));
// undefined
await git.branch({
...dirMeta,
ref: 'newBranch',
checkout: true,
})
// {(S)} -> [A]
// adding new history.
await quickCommit('B', 'alternative');
// S -> [A]
// \ -> {(B)}
console.log('head', await shortLog({}));
// head [
// 'B\n: 2f91269317ff35d7b56b3b3b0e285cf9b990b403',
// 'S\n: 95c49e1126dafd347a51bc20d1af845d4f123210'
// ]
console.log(await git.listBranches(dirMeta));
// [ 'main', 'newBranch' ]
console.log(await git.currentBranch(dirMeta));
// newBranch
// --------- switching over branches
// The ole switch-a-roo
// 1. rename main to oldMain
// 2. rename newBranch to main
// 3. delete oldMain
await quickRename('main', 'oldMain');
await quickRename('newBranch', 'main');
// S -> (A)
// \ -> {[B]}
// await git.deleteBranch({
// ...dirMeta,
// ref: 'oldMain'
// })
// --------
console.log('head', await shortLog({}));
// head [
// 'B\n: 2f91269317ff35d7b56b3b3b0e285cf9b990b403',
// 'S\n: 95c49e1126dafd347a51bc20d1af845d4f123210'
// ]
console.log('main', await shortLog({ref: 'main'}));
// main [
// 'B\n: 2f91269317ff35d7b56b3b3b0e285cf9b990b403',
// 'S\n: 95c49e1126dafd347a51bc20d1af845d4f123210'
// ]
console.log('oldMain', await shortLog({ref: 'oldMain'}));
// oldMain [
// 'A\n: b13c65fdc1e600802106822d111cdc2998eab0ef',
// 'S\n: 95c49e1126dafd347a51bc20d1af845d4f123210'
// ]
console.log(await git.listBranches(dirMeta));
// [ 'main', 'oldMain' ]
console.log(await git.currentBranch(dirMeta));
// main |
I'll have to review how the commit messages are generated. I recall there being an issue with it. It's low priority for now. |
The constant |
I've kept other constants in the utils usually in all other domains, so I kept it consistent. |
The GC operation seems trickier than I expected. Isogit doesn't provide any features for removing commits. This means we need to walk the git data structure and remove any object files we don't need from the FS directly. But I don't know if just deleting the objects is all you need to do. In any case this requires a bit of prototyping and testing. As a first order solution we can just walk the commits and only remove the commit objects. this should remove the commits we don't need and prevent checking them out. However this doesn't remove the underlying files. To do this properly I'll need to use a reach-ability algorithm to walk the the commits and underlying objects that are needed by existing branches and then remove any objects that are not in that set. I'll look into prototyping this now. |
Removing the commit object is sufficient to remove unwanted commits for now. I'll have to expand this to remove any unneeded objects in the git tree at some point. |
Core of the implementation is done here. just need to;
|
Need to create a new issue for task 7. |
Specification
The usage of
withF
andwithG
presents us a new API forVaultInternal
mutation and reading:Make sure to check the
remote
before writing anything.You also need to test what happens if the vault were to be checked out to a previous version, and is also considered a remote vault, does that mean pulling fails? If so, we can make it work, by temporarily checking out to the branch pointer, and completing the pull.
Make sure to use the
dirty
boolean to indicate dirty writing in the middle ofwriteF
andwriteG
.When performing operations with a vault, expect to pass a callback that receives the vault. I would want to align the API between
NodeConnectionManager
andVaultManager
. This requires further specification.As discussed
HEAD
andMASTER
will separately point to the same commit. When we commit using theref: 'HEAD
theHEAD
will be moved but theMASTER
will remain in place. TheMASTER
will need to be updated usinggit.writeRef
.When handling a commit in from previous history we need to check if the
HEAD
points to the same commit asMASTER
usinggit.resolveRef
. If they are different commits then it is a branching commit from the history. In this case we do the commit and update master to the resulting ref usinggit.writeRef
. The old commits between the branching point and the old master ref are deleted.When we create a new vault we need to check for dirty state. If the dirty flag is set in the metadata we need to checkout the ref that master points to and run a global GC operation. We need to iterate over all commits and check if they are part of the master commit chain.
Additional context
VaultInternal
#305version
#252 commentary.Tasks
VaultInternal
to usereadF/G
andwriteF/G
.boolean
metadata field.7. Look into aligning API betweenNodeConnectionManager
andVaultManager
. seperate issue? this issue isVaultInternal
scope and this task seems to beVaultManager
scope.The text was updated successfully, but these errors were encountered: