Last active
December 21, 2015 14:18
-
-
Save FrozenCow/6318468 to your computer and use it in GitHub Desktop.
An example of node-gitteh for the functions createBlobFromDisk, createTree and createCommit that can be found here: https://github.com/libgit2/node-gitteh/pull/63
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var gitteh = require('gitteh'); | |
function deepClone(val) { | |
if (val === null) { | |
return val; | |
} else if (val === undefined) { | |
return val; | |
} else if (val instanceof Array) { | |
return val.map(deepClone); | |
} else if (typeof val === 'object') { | |
var r = {}; | |
for(var k in val) { | |
if (val.hasOwnProperty(k)) { | |
r[k] = deepClone(val[k]); | |
} | |
} | |
return r; | |
} else { | |
return val; | |
} | |
} | |
var repoPath = 'repo'; | |
function initializeBareRepository(cb) { | |
gitteh.initRepository(repoPath, true, function(err,repo) { | |
if (err) { return cb(err); } | |
cb(null,repo); | |
}); | |
} | |
// Create first commit with one file named 'README.md'. | |
function createFirstCommit(repo,cb) { | |
// Info on createBlobFromDisk here: http://libgit2.github.com/libgit2/#HEAD/group/blob/git_blob_create_fromdisk | |
repo.createBlobFromDisk('README.md',function(err,blob) { | |
if (err) { return cb(err); } | |
// The content of README.md is now stored in the git repo as a blob. | |
// The argument 'blob' now contains the oid of said blob. | |
console.log('Blob',arguments); | |
// Info on createTree here: | |
// http://libgit2.github.com/libgit2/#HEAD/group/treebuilder/git_treebuilder_create | |
// http://libgit2.github.com/libgit2/#HEAD/group/treebuilder/git_treebuilder_insert | |
// http://libgit2.github.com/libgit2/#HEAD/group/treebuilder/git_treebuilder_write | |
repo.createTree([{ | |
id: blob, | |
name: 'README.md', | |
filemode: 0100644 // GIT_FILEMODE_BLOB: octal filemode from http://libgit2.github.com/libgit2/#HEAD/group/treebuilder/git_treebuilder_insert | |
}],function(err,tree) { | |
if (err) { return cb(err); } | |
// A tree is now stored in git that has one file with the name 'README.md' | |
// and has the content of blob. | |
// The argument 'tree' now contains the oid of said tree. | |
console.log('Tree',arguments); | |
// Info on createCommit here: http://libgit2.github.com/libgit2/#HEAD/group/commit/git_commit_create | |
repo.createCommit({ | |
updateref: 'HEAD', | |
message: 'First commit', | |
committer: { | |
name: 'FrozenCow', | |
email: '[email protected]' | |
}, | |
tree: tree, | |
parents: [] | |
// author is left out. | |
// update_ref is left out. (could be 'HEAD') | |
},function(err,commit) { | |
if (err) { return cb(err); } | |
// A commit is now stored in git with the tree as its content. | |
// It is the first commit, so it doesn't have any parents. | |
// The author is left out, since it is the same as the committer. | |
// The argument 'commit' now contains the oid of said commit (the SHA of the commit). | |
console.log('Commit',arguments); | |
cb(null, commit); | |
}); | |
}); | |
}); | |
} | |
// Create second commit, based on first commit, adding 'example.js' with a hard-coded string as its content. | |
function createSecondCommit(repo, commitid, cb) { | |
// First retrieve the asked commit to get its treeid. | |
repo.commit(commitid,function(err,commit) { | |
if (err) { return cb(err); } | |
// Next retrieve the tree of the commit. | |
repo.tree(commit.treeId,function(err,tree) { | |
if (err) { return cb(err); } | |
// In gitteh.coffee all returning objects are made immutable. | |
// That means we cannot add/remove entries to/from this tree object. | |
// To circumvent this we make a full clone so that it's mutable. | |
tree = deepClone(tree); | |
var fileContent = new Buffer('/* My first Javascript file! */'); | |
repo.createBlobFromBuffer(fileContent,function(err,blobid) { | |
if (err) { return cb(err); } | |
console.log('Blob',arguments); | |
tree.entries.push({ | |
id: blobid, | |
name: 'example.js', | |
filemode: 0100644 // GIT_FILEMODE_BLOB | |
}); | |
repo.createTree(tree.entries,function(err,treeid) { | |
console.log('Tree',arguments); | |
repo.createCommit({ | |
updateref: 'HEAD', | |
message: 'Second commit', | |
committer: { | |
name: 'FrozenCow', | |
email:' [email protected]' | |
}, | |
tree: treeid, | |
parents: [commitid] | |
},function(err,commitid) { | |
if (err) { return console.error(err); } | |
console.log('Commit',arguments); | |
cb(null,commitid); | |
}); | |
}); | |
}); | |
}); | |
}); | |
} | |
// Create third commit, moving 'example.js' to 'src/example.js' | |
// Each directory is represented as a tree a new tree is made for 'src'. | |
// Then again a new tree is made to incorporate the new 'src'-tree into | |
// the root-tree. | |
function createThirdCommit(repo, commitid, cb) { | |
// First retrieve the asked commit to get its treeid. | |
repo.commit(commitid,function(err,commit) { | |
if (err) { return cb(err); } | |
// Next retrieve the tree of the commit. | |
repo.tree(commit.treeId,function(err,tree) { | |
if (err) { return cb(err); } | |
var entries = deepClone(tree.entries); | |
// Retrieve and remove example.js entry. | |
var examplejsEntry = entries.reduce(function(prev,entry) { return entry.name === 'example.js' && entry || prev; }, null); | |
entries = entries.filter(function(entry) { return entry !== examplejsEntry; }); | |
// Create a new tree, representing the subdirectory 'src', with example.js as its only entry. | |
repo.createTree([examplejsEntry],function(err,subtreeid) { | |
if (err) { return cb(err); } | |
console.log('Tree',arguments); | |
// Add the newly created tree to the root tree. | |
entries.push({ | |
id: subtreeid, | |
name: 'src', | |
filemode: 0040000 // GIT_FILEMODE_TREE | |
}); | |
repo.createTree(entries,function(err,treeid) { | |
if (err) { return cb(err); } | |
// Commit the new tree. | |
repo.createCommit({ | |
updateref: 'HEAD', | |
message: 'Third commit: moved example.js to src/example.js', | |
committer: { | |
name: 'FrozenCow', | |
email:' [email protected]' | |
}, | |
tree: treeid, | |
parents: [commitid] | |
},function(err,commitid) { | |
if (err) { return console.error(err); } | |
console.log('Commit',arguments); | |
cb(null,commitid); | |
}); | |
}); | |
}); | |
}); | |
}); | |
} | |
initializeBareRepository(function(err,repo) { | |
if (err) { return console.error(err); } | |
createFirstCommit(repo,function(err,commitid) { | |
if (err) { return console.error(err); } | |
console.log('created first commit',commitid); | |
createSecondCommit(repo,commitid,function(err,commitid) { | |
if (err) { return console.error(err); } | |
console.log('created second commit',commitid); | |
createThirdCommit(repo,commitid,function(err,commitid) { | |
if (err) { return console.error(err); } | |
console.log('created third commit',commitid); | |
}); | |
}); | |
}); | |
}); | |
/* | |
Shows all diffs of every commit: | |
$ (cd repo && git log -p --full-diff) | |
Shows the full tree (recursively) of a certain commit: | |
$ (cd repo && git ls-tree -r HEAD) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment