Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions example/merge-cleanly.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
var nodegit = require('../');
var path = require('path');
var Promise = require('nodegit-promise');
var promisify = require('promisify-node');
var fse = promisify(require('fs-extra'));
fse.ensureDir = promisify(fse.ensureDir);

var ourFileName = 'ourNewFile.txt';
var ourFileContent = 'I like Toll Roads. I have an EZ-Pass!';
var ourBranchName = "ours";

var theirFileName = 'theirNewFile.txt';
var theirFileContent = "I'm skeptical about Toll Roads";
var theirBranchName = "theirs";

var repoDir = '../../newRepo';

var repository;
var ourCommit;
var theirCommit;
var ourBranch;
var theirBranch;

var ourSignature = nodegit.Signature.create("Ron Paul", "RonPaul@TollRoadsRBest.info", 123456789, 60);
var theirSignature = nodegit.Signature.create("Greg Abbott", "Gregggg@IllTollYourFace.us", 123456789, 60);

// Create a new repository in a clean directory, and add our first file
fse.remove(path.resolve(__dirname, repoDir))
.then(function() {
return fse.ensureDir(path.resolve(__dirname, repoDir));
})
.then(function() {
return nodegit.Repository.init(path.resolve(__dirname, repoDir), 0);
})
.then(function(repo) {
repository = repo;
return fse.writeFile(path.join(repository.workdir(), ourFileName), ourFileContent);
})

// Load up the repository index and make our initial commit to HEAD
.then(function() {
return repository.openIndex();
})
.then(function(index) {
index.read(1);
index.addByPath(ourFileName);
index.write()

return index.writeTree();
})
.then(function(oid) {
return repository.createCommit('HEAD', ourSignature, ourSignature, 'we made a commit', oid, []);
})

// Get commit object from the oid, and create our new branches at that position
.then(function(commitOid) {
return repository.getCommit(commitOid).then(function(commit) {
ourCommit = commit;
}).then(function() {
return repository.createBranch(ourBranchName, commitOid).then(function(branch) {
ourBranch = branch;
return repository.createBranch(theirBranchName, commitOid);
});
});
})

// Create a new file, stage it and commit it to our second branch
.then(function(branch) {
theirBranch = branch;
return fse.writeFile(path.join(repository.workdir(), theirFileName), theirFileContent);
})
.then(function() {
return repository.openIndex();
})
.then(function(index) {
index.read(1);
index.addByPath(theirFileName);
index.write()

return index.writeTree();
})
.then(function(oid) {
// You don't have to change head to make a commit to a different branch.
return repository.createCommit(theirBranch.name(), theirSignature, theirSignature, 'they made a commit', oid, [ourCommit]);
})
.then(function(commitOid) {
return repository.getCommit(commitOid).then(function(commit) {
theirCommit = commit;
});
})


// Merge the two commits
.then(function() {
return nodegit.Merge.commits(repository, ourCommit, theirCommit);
})


// Merging returns an index that isn't backed by the repository.
// You have to manually check for merge conflicts. If there are none
// you just have to write the index. You do have to write it to
// the repository instead of just writing it.
.then(function(index) {
if (!index.hasConflicts()) {
index.write()
return index.writeTreeTo(repository);
}
})


// Create our merge commit back on our branch
.then(function(oid) {
return repository.createCommit(ourBranch.name(), ourSignature, ourSignature, 'we merged their commit', oid, [ourCommit, theirCommit]);
})
.done(function(commitId) {
// We never changed the HEAD after the initial commit; it should still be the same as master.
console.log('New Commit: ', commitId);
});
169 changes: 169 additions & 0 deletions example/merge-with-conflicts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
var nodegit = require('../');
var path = require('path');
var Promise = require('nodegit-promise');
var promisify = require('promisify-node');
var fse = promisify(require('fs-extra'));
fse.ensureDir = promisify(fse.ensureDir);

var repoDir = '../../newRepo';
var fileName = 'newFile.txt';

var baseFileContent = 'All Bobs are created equal. ish.\n';
var ourFileContent = "Big Bobs are best, IMHO.\n";
var theirFileContent = "Nobody expects the small Bobquisition!\n";
var finalFileContent = "Big Bobs are beautiful, and the small are unexpected!\n";

var baseSignature = nodegit.Signature.create("Peaceful Bob", "justchill@bob.net", 123456789, 60);
var ourSignature = nodegit.Signature.create("Big Bob", "impressive@bob.net", 123456789, 60);
var theirSignature = nodegit.Signature.create("Small Bob", "underestimated@bob.net", 123456789, 60);

var ourBranchName = "ours";
var theirBranchName = "theirs";

var repository;
var baseCommit;
var baseCommitOid;
var ourCommit;
var theirCommit;
var ourBranch;
var theirBranch;

// Create a new repository in a clean directory, and add our first file
fse.remove(path.resolve(__dirname, repoDir))
.then(function() {
return fse.ensureDir(path.resolve(__dirname, repoDir));
})
.then(function() {
return nodegit.Repository.init(path.resolve(__dirname, repoDir), 0);
})
.then(function(repo) {
repository = repo;
return fse.writeFile(path.join(repository.workdir(), fileName), baseFileContent);
})


// Load up the repository index and make our initial commit to HEAD
.then(function() {
return repository.openIndex();
})
.then(function(index) {
index.read(1);
index.addByPath(fileName);
index.write()

return index.writeTree();
})
.then(function(oid) {
return repository.createCommit('HEAD', baseSignature, baseSignature, 'bobs are all ok', oid, []);
})
.then(function(commitOid) {
baseCommitOid = commitOid;
return repository.getCommit(commitOid).then(function(commit) {
baseCommit = commit;
});
})


// create our branches
.then(function() {
return repository.createBranch(ourBranchName, baseCommitOid).then(function(branch) {
ourBranch = branch;
});
})
.then(function() {
return repository.createBranch(theirBranchName, baseCommitOid).then(function(branch) {
theirBranch = branch;
});
})


// Write and commit our version of the file
.then(function() {
return fse.writeFile(path.join(repository.workdir(), fileName), ourFileContent);
})
.then(function() {
return repository.openIndex().then(function(index) {
index.read(1);
index.addByPath(fileName);
index.write()

return index.writeTree();
});
})
.then(function(oid) {
return repository.createCommit(ourBranch.name(), ourSignature, ourSignature, 'lol big bobs :yesway:', oid, [baseCommit]);
})
.then(function(commitOid) {
return repository.getCommit(commitOid).then(function(commit) {
ourCommit = commit;
});
})


// Write and commit their version of the file
.then(function() {
return fse.writeFile(path.join(repository.workdir(), fileName), theirFileContent);
})
.then(function() {
return repository.openIndex().then(function(index) {
index.read(1);
index.addByPath(fileName);
index.write()

return index.writeTree();
});
})
.then(function(oid) {
return repository.createCommit(theirBranch.name(), theirSignature, theirSignature, 'lol big bobs :poop:', oid, [baseCommit]);
})
.then(function(commitOid) {
return repository.getCommit(commitOid).then(function(commit) {
theirCommit = commit;
});
})


// move the head to our branch, just to keep things tidy
.then(function() {
return nodegit.Reference.lookup(repository, 'HEAD').then(function(head) {
return head.symbolicSetTarget(ourBranch.name(), ourSignature, "");
})
})


// Merge their branch into our branch
.then(function() {
return nodegit.Merge.commits(repository, ourCommit, theirCommit, null);
})

// Merging returns an index that isn't backed by the repository.
// You have to write it to the repository instead of just writing it.
.then(function(index) {
if (index.hasConflicts()) {
console.log('Conflict time!');

// if the merge had comflicts, solve them
// (in this case, we simply overwrite the file)
fse.writeFileSync(path.join(repository.workdir(), fileName), finalFileContent);
}
})

// we need to get a new index as the other one isnt backed to
// the repository in the usual fashion, and just behaves weirdly
.then(function() {
return repository.openIndex().then(function(index) {

index.read(1);
index.addByPath(fileName);
index.write();

return index.writeTree();
});
})
.then(function(oid) {
// create the new merge commit on our branch
return repository.createCommit(ourBranch.name(), baseSignature, baseSignature, 'Stop this bob sized fued', oid, [ourCommit, theirCommit]);
})
.done(function(commitId) {
console.log('New Commit: ', commitId);
});
23 changes: 17 additions & 6 deletions generate/descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -630,9 +630,6 @@
"isOptional": true
}
}
},
"git_index_write_tree_to": {
"ignore": true
}
}
},
Expand Down Expand Up @@ -668,15 +665,19 @@
"git_merge_analysis": {
"ignore": true
},
"git_merge_base": {
"ignore": true
},
"git_merge_base_many": {
"ignore": true
},
"git_merge_base_octopus": {
"ignore": true
},
"git_merge_commits": {
"args": {
"opts": {
"isOptional": true
}
}
},
"git_merge_file": {
"ignore": true
},
Expand Down Expand Up @@ -1027,6 +1028,16 @@
},
"git_reference_next_name": {
"ignore": true
},
"git_reference_symbolic_set_target": {
"args": {
"signature": {
"isOptional": true
},
"log_message": {
"isOptional": true
}
}
}
}
},
Expand Down
19 changes: 19 additions & 0 deletions generate/libgit2-supplement.json
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,16 @@
"git_odb_object_size",
"git_odb_object_type"
]
],
[
"merge_head",
[
"git_merge_head_free",
"git_merge_head_from_fetchhead",
"git_merge_head_from_id",
"git_merge_head_from_ref",
"git_merge_head_id"
]
]
]
},
Expand All @@ -274,6 +284,15 @@
"git_odb_object_size",
"git_odb_object_type"
]
},
"merge": {
"functions": [
"git_merge_head_free",
"git_merge_head_from_fetchhead",
"git_merge_head_from_id",
"git_merge_head_from_ref",
"git_merge_head_id"
]
}
}
}
22 changes: 22 additions & 0 deletions lib/merge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var NodeGit = require("../");
var normalizeOptions = require("./util/normalize_options");

var Merge = NodeGit.Merge;
var mergeCommits = Merge.commits;

/**
* Merge 2 commits together and create an new index that can
* be used to create a merge commit.
*
* @param repo Repository that contains the given commits
* @param ourCommit The commit that reflects the destination tree
* @oaram theirCommit The commit to merge into ourCommit
* @param options The merge tree options (null for default)
*/
Merge.commits = function(repo, ourCommit, theirCommit, options) {
options = normalizeOptions(options, NodeGit.MergeOptions);

return mergeCommits.call(this, repo, ourCommit, theirCommit, options);
};

module.exports = Merge;
Loading