Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: toolness/git-browserid-cors
base: 3c5fab6785
...
head fork: toolness/git-browserid-cors
compare: 1adc87f537
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Aug 06, 2012
@toolness added Git.pull to git.js 3aedbd5
Commits on Aug 07, 2012
@toolness added /pull endpoint 1adc87f
View
21 git.js
@@ -19,12 +19,18 @@ function Git(options) {
cs = CommandSerializer(),
self = {};
- function git(args, cb) {
+ function git(args, env, cb) {
+ if (typeof(env) == 'function') {
+ cb = env;
+ env = undefined;
+ }
+ env = env || {};
+
var cmdline = 'git ' + args.join(' '),
stderr = [],
stdout = [],
exitCode = undefined,
- process = spawn(executable, args, {cwd: rootDir});
+ process = spawn(executable, args, {cwd: rootDir, env: env});
if (!cb)
throw new Error('no callback given for: ' + cmdline);
@@ -129,6 +135,17 @@ function Git(options) {
cb(err, stdout.split('\n').slice(0, -1));
});
},
+ pull: function(options, cb) {
+ var env = {};
+
+ if (options.email)
+ env['GIT_COMMITTER_EMAIL'] = options.email;
+ if (options.name)
+ env['GIT_COMMITTER_NAME'] = options.name;
+
+ git(['pull', '--ff-only', options.repository, options.refspec],
+ env, cb);
+ },
end: function(cb) {
process.nextTick(function() { cb(null); });
},
View
31 simple-git-server.js
@@ -1,5 +1,6 @@
var _ = require('underscore'),
path = require('path'),
+ url = require('url'),
express = require('express');
function username(email) {
@@ -82,6 +83,32 @@ function makeListHandler(git) {
};
}
+function makePullHandler(git) {
+ return function(req, res) {
+ if (!req.user)
+ return res.send(403);
+
+ if (!(typeof(req.body.repository) == 'string'))
+ return res.send('repository expected', 400);
+ var repo = url.parse(req.body.repository);
+ if (!(repo.protocol == "git:" || repo.protocol == "http:" ||
+ repo.protocol == "https:"))
+ return res.send('invalid repository', 400);
+ if (!(typeof(req.body.refspec) == 'string'))
+ return res.send('refspec expected', 400);
+
+ git.pull({
+ repository: req.body.repository,
+ refspec: req.body.refspec,
+ email: req.user.email,
+ name: username(req.user.email) + ' from ' + req.user.origin
+ }, function(err) {
+ if (err) return res.send('an unknown error occurred', 500);
+ return res.send(200);
+ });
+ }
+}
+
module.exports = function SimpleGitServer(config) {
var git = config.git;
var bic = config.browserIDCORS || require('browserid-cors')();
@@ -92,6 +119,7 @@ module.exports = function SimpleGitServer(config) {
self.handleCommit = makeCommitHandler(git, function postCommit(git) {
if (git.cmd) git.cmd(['update-server-info']);
});
+ self.handlePull = makePullHandler(git);
self.use(express.bodyParser());
self.use(bic.accessToken);
@@ -99,7 +127,8 @@ module.exports = function SimpleGitServer(config) {
self.post('/token', bic.handleTokenRequest);
self.post('/commit', self.handleCommit);
self.get('/ls', self.handleList);
-
+ self.post('/pull', self.handlePull);
+
if (git.abspath)
self.use('/static', express.static(git.abspath()));
View
32 test/test-git.js
@@ -31,6 +31,38 @@ describe('Git', function() {
afterEach(nukeRootDir);
+ it('should pull', function(done) {
+ var git2dir = rootDir + '/repo2';
+ var git2 = Git({rootDir: git2dir});
+
+ fs.mkdirSync(git2dir);
+
+ git.init()
+ .addFile('blah.txt', 'hello')
+ .commit({author: 'Foo <foo@foo.org>', message: 'origination.'})
+ .end(function(err) {
+ if (err) return done(err);
+
+ git2.init()
+ .pull({
+ repository: rootDir,
+ refspec: 'master',
+ email: 'blap@blap.org',
+ name: 'Blap Person'
+ })
+ .end(function(err) {
+ if (err) return done(err);
+ var blahTxt = fs.readFileSync(git2.abspath('blah.txt'), 'utf8');
+ var reflogPath = git2.abspath('.git/logs/HEAD')
+ var reflog = fs.readFileSync(reflogPath, 'utf8');
+ expect(blahTxt).to.be('hello');
+ expect(reflog).to.match(/blap@blap\.org/);
+ expect(reflog).to.match(/Blap Person/);
+ done();
+ });
+ });
+ });
+
it('should accept Buffer objects to addFile()', function(done) {
git.init()
.addFile('blah.txt', new Buffer([1,2,3]))
View
76 test/test-simple-git-server.js
@@ -288,6 +288,82 @@ describe("SimpleGitServer", function() {
.expect(200, {files: ['bloop/bap.js']}, done);
});
+ it("should fail when pulling w/ no repository", function(done) {
+ request(cfg(SimpleGitServer({git: {}})))
+ .post('/pull')
+ .set('X-Access-Token', 'abcd')
+ .send()
+ .expect(400, "repository expected", done);
+ });
+
+ it("should fail when pulling w/ invalid repository", function(done) {
+ request(cfg(SimpleGitServer({git: {}})))
+ .post('/pull')
+ .set('X-Access-Token', 'abcd')
+ .send({repository: 'lol'})
+ .expect(400, "invalid repository", done);
+ });
+
+ it("should fail when pulling w/ no refspec", function(done) {
+ request(cfg(SimpleGitServer({git: {}})))
+ .post('/pull')
+ .set('X-Access-Token', 'abcd')
+ .send({repository: 'http://blah.org/myrepo'})
+ .expect(400, "refspec expected", done);
+ });
+
+ it("should fail when pulling w/ no token", function(done) {
+ request(cfg(SimpleGitServer({git: {}})))
+ .post('/pull')
+ .send()
+ .expect(403, done);
+ });
+
+ it("should return 500 on pull failure", function(done) {
+ request(cfg(SimpleGitServer({
+ git: {
+ pull: function(options, cb) {
+ cb('fail fail fail!');
+ }
+ }
+ })))
+ .post('/pull')
+ .set('X-Access-Token', 'abcd')
+ .send({
+ repository: 'http://blah.org/myrepo',
+ refspec: 'master'
+ })
+ .expect(500, 'an unknown error occurred', done);
+ });
+
+ it("should pull", function(done) {
+ var pullOptions;
+ request(cfg(SimpleGitServer({
+ git: {
+ pull: function(options, cb) {
+ pullOptions = options;
+ cb(null);
+ }
+ }
+ })))
+ .post('/pull')
+ .set('X-Access-Token', 'abcd')
+ .send({
+ repository: 'http://blah.org/myrepo',
+ refspec: 'master'
+ })
+ .expect(200, function(err) {
+ if (err) return done(err);
+ expect(pullOptions).to.eql({
+ repository: 'http://blah.org/myrepo',
+ refspec: 'master',
+ email: 'foo@foo.org',
+ name: 'foo from http://bar.org'
+ });
+ done();
+ });
+ });
+
it("should have /token endpoint", function(done) {
request(cfg(SimpleGitServer({git: {}})))
.post('/token')

No commit comments for this range

Something went wrong with that request. Please try again.