2016-03-26 22:16:47 +05:30
|
|
|
var crypto = require("crypto");
|
|
|
|
var Logger = require('../../logger');
|
2016-03-27 18:27:54 +05:30
|
|
|
var log = new Logger.Log();
|
2016-03-27 23:02:31 +05:30
|
|
|
var _ = require("lodash");
|
2016-03-27 18:27:54 +05:30
|
|
|
//var log = new Logger.Log(1);
|
2016-03-26 22:16:47 +05:30
|
|
|
|
2016-03-27 11:00:44 +05:30
|
|
|
|
2016-03-26 22:16:47 +05:30
|
|
|
var commits = {};
|
|
|
|
var head = null;
|
|
|
|
var branches = { "master" : head };
|
|
|
|
var curBranch = "master";
|
2016-03-27 11:00:44 +05:30
|
|
|
var direction = "LR";
|
2016-03-27 16:13:07 +05:30
|
|
|
var seq = 0;
|
2016-03-26 22:16:47 +05:30
|
|
|
|
|
|
|
function getId() {
|
|
|
|
return crypto.randomBytes(20).toString('hex').substring(0, 7);
|
|
|
|
}
|
2016-03-27 11:00:44 +05:30
|
|
|
|
2016-03-27 16:13:07 +05:30
|
|
|
|
2016-03-27 18:27:54 +05:30
|
|
|
function isfastforwardable(currentCommit, otherCommit) {
|
2016-03-27 16:13:07 +05:30
|
|
|
var currentSeq = currentCommit.seq;
|
|
|
|
var otherSeq = otherCommit.seq;
|
|
|
|
|
|
|
|
log.debug(commits);
|
|
|
|
log.debug(currentCommit, otherCommit);
|
|
|
|
while (currentSeq <= otherSeq && currentCommit != otherCommit) {
|
2016-03-27 18:27:54 +05:30
|
|
|
// only if other branch has more commits
|
2016-03-27 17:53:01 +05:30
|
|
|
if (otherCommit.parent == null) break;
|
2016-03-27 18:27:54 +05:30
|
|
|
if (Array.isArray(otherCommit.parent)){
|
|
|
|
return isfastforwardable(currentCommit, otherCommit.parent[0]) ||
|
|
|
|
isfastforwardable(currentCommit, otherCommit.parent[1])
|
|
|
|
} else {
|
|
|
|
otherCommit = commits[otherCommit.parent];
|
|
|
|
}
|
2016-03-27 16:13:07 +05:30
|
|
|
}
|
|
|
|
log.debug(currentCommit.id, otherCommit.id);
|
|
|
|
return currentCommit.id == otherCommit.id;
|
|
|
|
}
|
2016-03-27 17:35:29 +05:30
|
|
|
|
2016-03-27 18:27:54 +05:30
|
|
|
function isReachableFrom(currentCommit, otherCommit) {
|
2016-03-27 17:35:29 +05:30
|
|
|
var currentSeq = currentCommit.seq;
|
|
|
|
var otherSeq = otherCommit.seq;
|
2016-03-27 18:27:54 +05:30
|
|
|
if (currentSeq > otherSeq) return isfastforwardable(otherCommit, currentCommit);
|
2016-03-27 17:35:29 +05:30
|
|
|
return false;
|
|
|
|
}
|
2016-03-27 23:02:31 +05:30
|
|
|
|
2016-03-27 11:00:44 +05:30
|
|
|
exports.setDirection = function(dir) {
|
|
|
|
direction = dir;
|
|
|
|
}
|
2016-03-27 23:02:31 +05:30
|
|
|
|
2016-03-27 11:22:30 +05:30
|
|
|
exports.commit = function(msg) {
|
2016-03-26 22:16:47 +05:30
|
|
|
var commit = { id: getId(),
|
2016-03-27 11:00:44 +05:30
|
|
|
message: msg,
|
2016-03-27 16:13:07 +05:30
|
|
|
seq: seq++,
|
2016-03-26 22:16:47 +05:30
|
|
|
parent: head == null ? null : head.id};
|
|
|
|
head = commit;
|
|
|
|
commits[commit.id] = commit;
|
|
|
|
branches[curBranch] = commit.id;
|
|
|
|
log.debug("in pushCommit");
|
|
|
|
}
|
|
|
|
|
2016-03-27 11:22:30 +05:30
|
|
|
exports.branch = function(name) {
|
2016-03-27 11:00:44 +05:30
|
|
|
branches[name] = head != null ? head.id: null;
|
2016-03-26 22:16:47 +05:30
|
|
|
log.debug("in createBranch");
|
|
|
|
}
|
|
|
|
|
2016-03-27 17:35:29 +05:30
|
|
|
exports.merge = function(otherBranch) {
|
2016-03-27 18:27:54 +05:30
|
|
|
var currentCommit = commits[branches[curBranch]];
|
|
|
|
var otherCommit = commits[branches[otherBranch]];
|
|
|
|
if (isReachableFrom(currentCommit, otherCommit)) {
|
2016-03-27 17:35:29 +05:30
|
|
|
log.debug("Already merged");
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 18:27:54 +05:30
|
|
|
if (isfastforwardable(currentCommit, otherCommit)){
|
2016-03-27 17:35:29 +05:30
|
|
|
branches[curBranch] = branches[otherBranch];
|
2016-03-27 16:13:07 +05:30
|
|
|
head = commits[branches[curBranch]];
|
2016-03-27 17:53:01 +05:30
|
|
|
} else {
|
|
|
|
// create merge commit
|
|
|
|
var commit = {
|
|
|
|
id: getId(),
|
|
|
|
message: 'merged branch ' + otherBranch + ' into ' + curBranch,
|
|
|
|
seq: seq++,
|
|
|
|
parent: [head == null ? null : head.id, commits[branches[otherBranch]]]
|
|
|
|
};
|
|
|
|
head = commit;
|
|
|
|
commits[commit.id] = commit;
|
|
|
|
branches[curBranch] = commit.id;
|
2016-03-27 16:13:07 +05:30
|
|
|
}
|
|
|
|
log.debug(branches);
|
2016-03-26 22:16:47 +05:30
|
|
|
log.debug("in mergeBranch");
|
|
|
|
}
|
|
|
|
|
2016-03-27 11:00:44 +05:30
|
|
|
exports.checkout = function(branch) {
|
|
|
|
log.debug("in checkout");
|
|
|
|
curBranch = branch;
|
|
|
|
var id = branches[curBranch];
|
|
|
|
head = commits[id];
|
|
|
|
}
|
2016-03-27 14:45:26 +05:30
|
|
|
|
|
|
|
exports.reset = function(ref) {
|
|
|
|
log.debug("in reset");
|
|
|
|
var commit = ref == 'HEAD' ? head : commits[branches[ref]];
|
|
|
|
head = commit;
|
|
|
|
branches[curBranch] = commit.id;
|
|
|
|
}
|
|
|
|
|
2016-03-27 23:02:31 +05:30
|
|
|
exports.prettyPrint = function() {
|
|
|
|
var commitArr = Object.keys(commits).map(function (key) {
|
|
|
|
return commits[key];
|
|
|
|
});
|
|
|
|
var sortedCommits = _.orderBy(commitArr, ['seq'], ['desc']);
|
|
|
|
console.log(sortedCommits);
|
|
|
|
}
|
|
|
|
|
2016-03-27 11:22:30 +05:30
|
|
|
exports.clear = function () {
|
2016-03-26 22:16:47 +05:30
|
|
|
commits = {};
|
|
|
|
head = null;
|
|
|
|
branches = { "master" : head };
|
|
|
|
curBranch = "master";
|
2016-03-27 16:13:07 +05:30
|
|
|
seq =0;
|
2016-03-26 22:16:47 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
exports.getBranches = function() { return branches; }
|
|
|
|
exports.getCommits = function() { return commits; }
|
|
|
|
exports.getCurrentBranch = function() { return curBranch; }
|
2016-03-27 11:00:44 +05:30
|
|
|
exports.getDirection = function() { return direction; }
|
2016-03-27 14:45:26 +05:30
|
|
|
exports.getHead = function() { return head; }
|