Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 515428 - Can't calculate incoming/outgoing changes between two un…
…related histories

To determine the incoming and outgoing changes between two branches,
a common ancestor is used for determining when the two branches
diverged and which commits they don't share. In the event of two
unrelated histories, the two branches will not have a common ancestor
commit. In such a case, all the commits of each individual branch
should be considered as being incoming/outgoing.

Signed-off-by: Remy Suen <remy.suen@gmail.com>
  • Loading branch information
rcjsuen committed Apr 19, 2017
1 parent f461f30 commit 2337ad3
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 11 deletions.
24 changes: 17 additions & 7 deletions modules/orionode/lib/git/commit.js
Expand Up @@ -520,19 +520,29 @@ function getCommitLog(req, res) {
})
.then(function(commit) {
commit1 = commit;
return git.Merge.base(repo, commit0, commit1).then(function(oid){
return oid;
// find the common ancestor for calculating incoming/outgoing changes
return git.Merge.base(repo, commit0, commit1)
.catch(function(err) {
if (err.message === "No merge base found") {
return null;
}
throw err;
});
})
.then(function(oid) {
mergeBaseCommitOid = oid;
var revWalkForCounting1 = repo.createRevWalk();
revWalkForCounting1.sorting(git.Revwalk.SORT.TOPOLOGICAL);
revWalkForCounting1.pushRange(mergeBaseCommitOid.tostrS() + ".." + commit0.id().tostrS()); //count for incomings

var revWalkForCounting2 = repo.createRevWalk();
revWalkForCounting1.sorting(git.Revwalk.SORT.TOPOLOGICAL);
revWalkForCounting2.sorting(git.Revwalk.SORT.TOPOLOGICAL);
revWalkForCounting2.pushRange(mergeBaseCommitOid.tostrS() + ".." + commit1.id().tostrS()); // count for outgoing
if (oid === null) {
// no common ancestor, just count everything
revWalkForCounting1.push(commit0.id().tostrS()); // incoming changes
revWalkForCounting2.push(commit1.id().tostrS()); // outgoing changes
} else {
mergeBaseCommitOid = oid;
revWalkForCounting1.pushRange(mergeBaseCommitOid.tostrS() + ".." + commit0.id().tostrS()); // incoming changes
revWalkForCounting2.pushRange(mergeBaseCommitOid.tostrS() + ".." + commit1.id().tostrS()); // outgoing changes
}

return Promise.all([countCommit(revWalkForCounting1),countCommit(revWalkForCounting2)]);
}).then(function(results){
Expand Down
59 changes: 55 additions & 4 deletions modules/orionode/test/test-git-api.js
Expand Up @@ -458,14 +458,15 @@ GitClient.prototype = {
});
},

compare: function(source, target) {
compare: function(source, target, parameters) {
var client = this;
this.tasks.push(function(resolve) {
source = util.encodeURIComponent(source);
target = util.encodeURIComponent(target);

request()
.get(CONTEXT_PATH + "/gitapi/commit/" + source + ".." + target + "/file/" + client.getName())
.get(CONTEXT_PATH + "/gitapi/commit/" + target + ".." + source + "/file/" + client.getName())
.query(parameters)
.expect(202)
.end(function(err, res) {
assert.ifError(err);
Expand Down Expand Up @@ -2044,8 +2045,58 @@ maybeDescribe("git", function() {
client.createBranch("other");
client.commit();
// compare master with the created branch
client.compare("refs/heads/master", "refs/heads/other");
client.start().then(function() {
client.compare("refs/heads/master", "refs/heads/other", { mergeBase: true });
client.start().then(function(result) {
assert.equal(result.AheadCount, 1);
assert.equal(result.BehindCount, 0);
finished();
})
.catch(function(err) {
finished(err);
});
});

it("bug 515428", function(finished) {
var repository;
var initial, modify, extra, extra2;
var name = "test.txt";
var unrelated = "unrelated.txt";

var client = new GitClient("merge-unrelated-identical-content");
client.init();
// create a file with content "A" in it
client.setFileContents(name, "A");
client.stage(name);
client.commit();
client.start().then(function(commit) {
initial = commit.Id;
// open the repository using NodeGit
var testPath = path.join(WORKSPACE, "merge-unrelated-identical-content");
return git.Repository.open(testPath);
})
.then(function(repo) {
repository = repo;
return repository.refreshIndex();
})
.then(function(index) {
// get the oid of the current repository state
return index.writeTree();
})
.then(function(oid) {
// using that oid, create a commit in another branch with no parent commit
return repository.createCommit("refs/heads/other",
git.Signature.default(repository),
git.Signature.default(repository),
"unrelated", oid, [ ]);
})
.then(function() {
// merge in the branch with an unrelated history
client.compare("refs/heads/master", "refs/heads/other", { mergeBase: true });
return client.start();
})
.then(function(result) {
assert.equal(result.AheadCount, 2);
assert.equal(result.BehindCount, 1);
finished();
})
.catch(function(err) {
Expand Down

0 comments on commit 2337ad3

Please sign in to comment.