handle merge commits in history walk

This commit is contained in:
Raghu Rajagopalan
2016-03-27 18:27:54 +05:30
parent 2d99ccfcda
commit d3caa9b97d
2 changed files with 40 additions and 13 deletions

View File

@@ -1,7 +1,7 @@
var crypto = require("crypto"); var crypto = require("crypto");
var Logger = require('../../logger'); var Logger = require('../../logger');
//var log = new Logger.Log(); var log = new Logger.Log();
var log = new Logger.Log(1); //var log = new Logger.Log(1);
var commits = {}; var commits = {};
@@ -16,29 +16,30 @@ function getId() {
} }
function isfastforwardable(current, other) { function isfastforwardable(currentCommit, otherCommit) {
var currentCommit = commits[branches[current]];
var currentSeq = currentCommit.seq; var currentSeq = currentCommit.seq;
var otherCommit = commits[branches[other]];
var otherSeq = otherCommit.seq; var otherSeq = otherCommit.seq;
log.debug(commits); log.debug(commits);
log.debug(currentCommit, otherCommit); log.debug(currentCommit, otherCommit);
while (currentSeq <= otherSeq && currentCommit != otherCommit) { while (currentSeq <= otherSeq && currentCommit != otherCommit) {
// only if source has more commits // only if other branch has more commits
if (otherCommit.parent == null) break; if (otherCommit.parent == null) break;
otherCommit = commits[otherCommit.parent]; if (Array.isArray(otherCommit.parent)){
return isfastforwardable(currentCommit, otherCommit.parent[0]) ||
isfastforwardable(currentCommit, otherCommit.parent[1])
} else {
otherCommit = commits[otherCommit.parent];
}
} }
log.debug(currentCommit.id, otherCommit.id); log.debug(currentCommit.id, otherCommit.id);
return currentCommit.id == otherCommit.id; return currentCommit.id == otherCommit.id;
} }
function isReachableFrom(current, other) { function isReachableFrom(currentCommit, otherCommit) {
var currentCommit = commits[branches[current]];
var currentSeq = currentCommit.seq; var currentSeq = currentCommit.seq;
var otherCommit = commits[branches[other]];
var otherSeq = otherCommit.seq; var otherSeq = otherCommit.seq;
if (currentSeq > otherSeq) return isfastforwardable(other, current); if (currentSeq > otherSeq) return isfastforwardable(otherCommit, currentCommit);
return false; return false;
} }
exports.setDirection = function(dir) { exports.setDirection = function(dir) {
@@ -61,11 +62,13 @@ exports.branch = function(name) {
} }
exports.merge = function(otherBranch) { exports.merge = function(otherBranch) {
if (isReachableFrom(curBranch, otherBranch)) { var currentCommit = commits[branches[curBranch]];
var otherCommit = commits[branches[otherBranch]];
if (isReachableFrom(currentCommit, otherCommit)) {
log.debug("Already merged"); log.debug("Already merged");
return; return;
} }
if (isfastforwardable(curBranch, otherBranch)){ if (isfastforwardable(currentCommit, otherCommit)){
branches[curBranch] = branches[otherBranch]; branches[curBranch] = branches[otherBranch];
head = commits[branches[curBranch]]; head = commits[branches[curBranch]];
} else { } else {

View File

@@ -153,4 +153,28 @@ describe('when parsing a gitGraph',function() {
expect(parser.yy.getBranches()["newbranch"]).not.toEqual(parser.yy.getBranches()["master"]); expect(parser.yy.getBranches()["newbranch"]).not.toEqual(parser.yy.getBranches()["master"]);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()["master"]); expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()["master"]);
}); });
it('it should handle ff merge when history walk has two parents (merge commit)', function () {
var str = 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'commit\n' +
'merge newbranch\n' +
'commit\n' +
'checkout newbranch\n' +
'merge master\n' ;
parser.parse(str);
var commits = parser.yy.getCommits();
console.log(commits);
expect(Object.keys(commits).length).toBe(6);
expect(parser.yy.getCurrentBranch()).toBe("newbranch");
expect(parser.yy.getBranches()["newbranch"]).toEqual(parser.yy.getBranches()["master"]);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()["master"]);
});
}); });