Skip to content

Instantly share code, notes, and snippets.

@FrozenCow
Last active December 21, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FrozenCow/6318468 to your computer and use it in GitHub Desktop.
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
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: 'frozencow@gmail.com'
},
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:' frozencow@gmail.com'
},
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:' frozencow@gmail.com'
},
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