Nodegit: How to modify a file and push the changes?
Asked Answered
D

2

14

Looked around for an example, but couldn't find one. The documentation is not explained and I could not figure it out.

How to modify a file (README.md for example), create a commit for the modified file and then push the commit to the server ?

Nodegit: http://www.nodegit.org/

Nodegit documentation: http://www.nodegit.org/nodegit

Daisy answered 26/5, 2014 at 12:39 Comment(2)
I am currently trying to figure this out too. That documenation is really vague and API not really that helpful. I suspect there will be repo.createCommit method involved somehow, but it's really confusing. Did you found anything on this ?Bowl
Oh, I have totally missed this, very useful examples ... github.com/nodegit/nodegit/tree/master/exampleBowl
T
16

There is an example of how to create/add and commit on their repo, which can help you with the modifying the file.

https://github.com/nodegit/nodegit/blob/master/examples/add-and-commit.js

Regarding the commit and push, here is the snippet of how my code looks like and i hope it helps you a bit. It took me quite a bit to figure this out and thanks to the guys on Gitter, i finaly found an answer.

The code look like this:

var path = require('path');

var nodegit = require('nodegit'),
    repoFolder = path.resolve(__dirname, 'repos/test/.git'),
    fileToStage = 'README.md';

var repo, index, oid, remote;

nodegit.Repository.open(repoFolder)
  .then(function(repoResult) {
    repo = repoResult;
    return repoResult.openIndex();
  })
  .then(function(indexResult) {
    index  = indexResult;

    // this file is in the root of the directory and doesn't need a full path
    index.addByPath(fileToStage);

    // this will write files to the index
    index.write();

    return index.writeTree();
  })
  .then(function(oidResult) {
    oid = oidResult;

    return nodegit.Reference.nameToId(repo, 'HEAD');
  })
  .then(function(head) {
    return repo.getCommit(head);
  })
  .then(function(parent) {
    author = nodegit.Signature.now('Author Name', '[email protected]');
    committer = nodegit.Signature.now('Commiter Name', '[email protected]');

    return repo.createCommit('HEAD', author, committer, 'Added the Readme file for theme builder', oid, [parent]);
  })
  .then(function(commitId) {
    return console.log('New Commit: ', commitId);
  })

  /// PUSH
  .then(function() {
    return repo.getRemote('origin');
  })
  .then(function(remoteResult) {
    console.log('remote Loaded');
    remote = remoteResult;
    remote.setCallbacks({
      credentials: function(url, userName) {
        return nodegit.Cred.sshKeyFromAgent(userName);
      }
    });
    console.log('remote Configured');

    return remote.connect(nodegit.Enums.DIRECTION.PUSH);
  })
  .then(function() {
    console.log('remote Connected?', remote.connected())

    return remote.push(
      ['refs/heads/master:refs/heads/master'],
      null,
      repo.defaultSignature(),
      'Push to master'
    )
  })
  .then(function() {
    console.log('remote Pushed!')
  })
  .catch(function(reason) {
    console.log(reason);
  })

Hope this helps.

Telefilm answered 6/3, 2015 at 1:14 Comment(3)
Tried to edit the post but it won't let me - there's a missing " on the line: nodegit.Signature.now("Commiter Name", "[email protected]");Rosenkranz
Can you clarify how much of this is needed if I just want to do this equivalent of "git commit -am <msg>"? I'm just trying to call repo.createCommitOnHead without adding any (new?) files and it never returns.Treatment
Even when I do exactly as it says, it gets to the createCommit call, and that never completes.Treatment
B
2

Rafael's solution works for sure although I might add that there is no needed to perform a .connect into the server. Here is a minimal approach on pushing a repo:

  • Pushing to master using only username and password authentication:

            //Previous calls
    
            }).then(function() {
                return repo.getRemote("origin"); //Get origin remote
            }).then(function(remote) {
                return remote.push(["refs/heads/master:refs/heads/master"], {
                    callbacks: {
                        credentials: function(url, userName) {
                            console.log("Requesting creds");
    
                            return NodeGit.Cred.userpassPlaintextNew("[USERNAME]", "[PASSWORD]");
                        }
                    }
                });
            }).then(function(err) {
                console.log("Push error number:");
                console.log(err);
            }).catch(function(err) {
                console.log(err);
            }).done(function(commitId) {
                console.log("All done");
            })
    
  • Pushing to myBranch over SSH auth:

            //Previous calls
    
            }).then(function() {
                return repo.getRemote("origin"); //Get origin remote
            }).then(function(remote) {
                return remote.push(["refs/heads/myBranch:refs/heads/myBranch"], {
                    callbacks: {
                        credentials: function(url, userName) {
                            console.log("Requesting creds");
                            return NodeGit.Cred.sshKeyFromAgent(userName);
                        }
                    }
                });
            }).then(function(err) {
                console.log("Push error number:");
                console.log(err);
            }).catch(function(err) {
                console.log(err);
            }).done(function(commitId) {
                console.log("All done");
            })
    
Bretbretagne answered 18/1, 2017 at 3:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.