pcottle.learnGitBranching/src/js/graph/index.js
2018-12-01 13:04:24 +07:00

167 lines
4.6 KiB
JavaScript

function invariant(truthy, reason) {
if (!truthy) {
throw new Error(reason);
}
}
var Graph = {
getOrMakeRecursive: function(
tree,
createdSoFar,
objID,
gitVisuals
) {
// circular dependency, should move these base models OUT of
// the git class to resolve this
var Git = require('../git');
var Commit = Git.Commit;
var Ref = Git.Ref;
var Branch = Git.Branch;
var Tag = Git.Tag;
if (createdSoFar[objID]) {
// base case
return createdSoFar[objID];
}
var getType = function(tree, id) {
if (tree.commits[id]) {
return 'commit';
} else if (tree.branches[id]) {
return 'branch';
} else if (id == 'HEAD') {
return 'HEAD';
} else if (tree.tags[id]) {
return 'tag';
}
throw new Error("bad type for " + id);
};
// figure out what type
var type = getType(tree, objID);
if (type == 'HEAD') {
var headJSON = tree.HEAD;
var HEAD = new Ref(Object.assign(
tree.HEAD,
{
target: this.getOrMakeRecursive(tree, createdSoFar, headJSON.target)
}
));
createdSoFar[objID] = HEAD;
return HEAD;
}
if (type == 'branch') {
var branchJSON = tree.branches[objID];
var branch = new Branch(Object.assign(
tree.branches[objID],
{
target: this.getOrMakeRecursive(tree, createdSoFar, branchJSON.target)
}
));
createdSoFar[objID] = branch;
return branch;
}
if (type == 'tag') {
var tagJSON = tree.tags[objID];
var tag = new Tag(Object.assign(
tree.tags[objID],
{
target: this.getOrMakeRecursive(tree, createdSoFar, tagJSON.target)
}
));
createdSoFar[objID] = tag;
return tag;
}
if (type == 'commit') {
// for commits, we need to grab all the parents
var commitJSON = tree.commits[objID];
var parentObjs = [];
commitJSON.parents.forEach(function(parentID) {
parentObjs.push(this.getOrMakeRecursive(tree, createdSoFar, parentID));
}, this);
var commit = new Commit(Object.assign(
commitJSON,
{
parents: parentObjs,
gitVisuals: this.gitVisuals
}
));
createdSoFar[objID] = commit;
return commit;
}
throw new Error('ruh rho!! unsupported type for ' + objID);
},
descendSortDepth: function(objects) {
return objects.sort(function(oA, oB) {
return oB.depth - oA.depth;
});
},
bfsFromLocationWithSet: function(engine, location, set) {
var result = [];
var pQueue = [engine.getCommitFromRef(location)];
while (pQueue.length) {
var popped = pQueue.pop();
if (set[popped.get('id')]) {
continue;
}
result.push(popped);
// keep searching
pQueue = pQueue.concat(popped.get('parents'));
}
return result;
},
getUpstreamSet: function(engine, ancestor) {
var commit = engine.getCommitFromRef(ancestor);
var ancestorID = commit.get('id');
var queue = [commit];
var exploredSet = {};
exploredSet[ancestorID] = true;
var addToExplored = function(rent) {
exploredSet[rent.get('id')] = true;
queue.push(rent);
};
while (queue.length) {
var here = queue.pop();
var rents = here.get('parents');
(rents || []).forEach(addToExplored);
}
return exploredSet;
},
getUniqueObjects: function(objects) {
var unique = {};
var result = [];
objects.forEach(function(object) {
if (unique[object.id]) {
return;
}
unique[object.id] = true;
result.push(object);
});
return result;
},
getDefaultTree: function() {
return JSON.parse(unescape("%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%2C%22type%22%3A%22branch%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22type%22%3A%22commit%22%2C%22parents%22%3A%5B%5D%2C%22author%22%3A%22Peter%20Cottle%22%2C%22createTime%22%3A%22Mon%20Nov%2005%202012%2000%3A56%3A47%20GMT-0800%20%28PST%29%22%2C%22commitMessage%22%3A%22Quick%20Commit.%20Go%20Bears%21%22%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22type%22%3A%22commit%22%2C%22parents%22%3A%5B%22C0%22%5D%2C%22author%22%3A%22Peter%20Cottle%22%2C%22createTime%22%3A%22Mon%20Nov%2005%202012%2000%3A56%3A47%20GMT-0800%20%28PST%29%22%2C%22commitMessage%22%3A%22Quick%20Commit.%20Go%20Bears%21%22%2C%22id%22%3A%22C1%22%7D%7D%2C%22HEAD%22%3A%7B%22id%22%3A%22HEAD%22%2C%22target%22%3A%22master%22%2C%22type%22%3A%22general%20ref%22%7D%7D"));
}
};
module.exports = Graph;