Nodegit - How do I stage and commit a file? (simple example!)
Asked Answered
B

1

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",
    "[email protected]", 123456789, 60);
  var committer = nodegit.Signature.create("Scott A Chacon",
    "[email protected]", 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!

Beginner answered 3/12, 2017 at 16:2 Comment(2)
did you ever figure this out?Charleencharlemagne
best I can say is to start reading through the git docs git-scm.com/book/en/v2/Git-Internals-Git-ReferencesHalfon
H
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", "[email protected]"); // build auth/committer
  const committer = git.Signature.now("Scott A Chacon", "[email protected]");
  // 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
Halfon answered 25/2, 2020 at 5:12 Comment(4)
So we only need first five lines to stage all files, no? Or do we need index.writeTree() to properly stage all files?Contraoctave
@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.Rossi
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.Bill
can you clarify? You mean your changes were staged but never committed? are you executing await repo.createCommit (with the await keyword)?Halfon

© 2022 - 2024 — McMap. All rights reserved.