7

Using Node-git I just want to:

  1. Open a repo (where a file has been written/updated)
  2. Stage the file
  3. Do commit

Using the git cli I would write something like this

cd repo    
git add file.js
git commit -m "Added file.js"

I'm trying to follow the examples here describing how to do it with nodegit but have a hard time following these lines of code:

.then(function() {
  return repo.refreshIndex();
})
.then(function(indexResult) {
  index = indexResult;
})
.then(function() {
  // this file is in the root of the directory and doesn't need a full path
  return index.addByPath(fileName);
})
.then(function() {
  // this file is in a subdirectory and can use a relative path
  return index.addByPath(path.join(directoryName, fileName));
})
.then(function() {
  // this will write both files to the index
  return index.write();
})
.then(function() {
  return index.writeTree();
})
.then(function(oidResult) {
  oid = oidResult;
  return nodegit.Reference.nameToId(repo, "HEAD");
})
.then(function(head) {
  return repo.getCommit(head);
})
.then(function(parent) {
  var author = nodegit.Signature.create("Scott Chacon",
    "schacon@gmail.com", 123456789, 60);
  var committer = nodegit.Signature.create("Scott A Chacon",
    "scott@github.com", 987654321, 90);

  return repo.createCommit("HEAD", author, committer, "message", oid, [parent]);
})
.done(function(commitId) {
  console.log("New Commit: ", commitId);
});

Does it have to be so long? What are the roles of repo.refreshIndex(), index.write(), index.writeTree() etc. etc.? The API-docs is not so beginner friendly.

Thankful for enlightenment!

Einar
  • 133
  • 1
  • 8

1 Answers1

5

This is my first time working with this lib, but I figured I'd answer anyway. It's a lot easier to follow the flow if you swap out the promises for await. I commented with my basic understanding of what's going on.

  const repo = await git.Repository.open(localNotesDir);
  const index = await repo.refreshIndex(); // read latest
  const files = await repo.getStatus(); // get status of all files
  files.forEach(file => index.addByPath(file.path())); // stage each file
  await index.write(); // flush changes to index
  const changes = await index.writeTree(); // get reference to a set of changes
  const head = await git.Reference.nameToId(repo, "HEAD"); // get reference to the current state
  const parent = await repo.getCommit(head); // get the commit for current state
  const author = git.Signature.now("Scott Chacon", "schacon@gmail.com"); // build auth/committer
  const committer = git.Signature.now("Scott A Chacon", "scott@github.com");
  // combine all info into commit and return hash
  const commitId = await repo.createCommit("HEAD", author, committer, "message", changes, [parent]);
  console.log('commitId', commitId);
  // changes and head are each oids. Read about them here:
  // https://hackage.haskell.org/package/gitlib-0.6.5/docs/Data-Git-Oid.html
  • 1
    So we only need first five lines to stage all files, no? Or do we need `index.writeTree()` to properly stage all files? – Ajit Jan 23 '21 at 16:22
  • @ajit I'm not sure, but you can try this out by adding just those lines and checking with `git status` to see what happened. – vinnybad Dec 23 '21 at 19:41
  • in my case it is showing commit on bitbucket website, but nothing changed in file, also in vscode , same file is in staging and changes. – Sunil Garg Mar 10 '23 at 13:44
  • can you clarify? You mean your changes were staged but never committed? are you executing `await repo.createCommit` (with the await keyword)? – Patrick Michaelsen Mar 11 '23 at 02:51