1
0
mirror of https://github.com/danog/gift.git synced 2024-11-26 20:04:47 +01:00

Merge branch 'master' of github.com:sentientwaffle/gift

* 'master' of github.com:sentientwaffle/gift:
  Clone using HTTPS to avoid authentication prompt
  Update README.md
  Disable Git.clone() test
  Git.init() extended with bare parameter
  Git.clone() added
  bump to 0.0.6
  locked down the signature of Repo#sync with unit tests and an accurate representation in the README
  [README] #sync
  [README] #remote_remove and #remote_push
  [README] #status, #identity and #identify
  for Travis: make use of Repo#identify to ensure that our repository has an identity set when running the #create_tag test
This commit is contained in:
Luke Plaster 2013-10-12 15:25:14 +02:00
commit b600af22b1
6 changed files with 182 additions and 16 deletions

View File

@ -1,5 +1,7 @@
# Gift
### Not active, see [this fork](https://github.com/notatestuser/gift)
[![Build Status](https://secure.travis-ci.org/sentientwaffle/gift.png?branch=master)](http://travis-ci.org/sentientwaffle/gift)
A simple Node.js wrapper for the Git CLI. The API is based on
@ -11,11 +13,37 @@ A simple Node.js wrapper for the Git CLI. The API is based on
# API
For existing repositories:
git = require 'gift'
repo = git "path/to/repo"
# => #<Repo>
Initialize a new repository:
git = require 'gift'
git.init "path/to/repo", (err, _repo) ->
repo = _repo
# => #<Repo>
Initialize a new bare repository:
git = require 'gift'
git.init "path/to/bare/repo", true, (err, _repo) ->
repo = _repo
# => #<Repo>
Clone a repository:
git = require 'gift'
git.clone "git@host:path/to/remote/repo.git", "path/to/local/clone/repo", (err, _repo) ->
repo = _repo
# => #<Repo>
## Repo
### `Repo#path`
`String` - The path to the repository.
@ -57,6 +85,16 @@ Get the difference between the trees.
The callback receives `(err, diffs)`.
### `Repo#identity(callback)`
Get the commit identity for this repository.
The callback receives `(err, actor)`, where `actor` is an Actor.
### `Repo#identify(actor, callback)`
Set your account's default identity for commits to this repository.
The callback receives `(err)`.
### `Repo#remotes(callback)`
Get the repository's remotes.
@ -70,12 +108,17 @@ Get the string names of each of the remotes.
### `Repo#remote_add(name, url, callback)`
Equivalent to `git remote add <name> <url>`.
### `Repo#remote_remove(name, callback)`
Remove a remote.
### `Repo#remote_fetch(name, callback)`
`git fetch <name>`
### `Repo#remote_push(name, callback)`
`git push <name>`
### `Repo#status(callback)`
The callback receives `(err, status)`.
Uses `--porcelain` to parse repository status in a way that is agnostic of system language. The callback receives `(err, status)`. See below for a definition of what `status` is.
### `Repo#create_branch(name, callback)`
Create a new branch with `name`, and call the callback when complete
@ -128,6 +171,16 @@ Commit some changes.
### `Repo#checkout(treeish, callback)`
`git checkout <treeish>`
### `Repo#sync([[remote, ]branch, ]callback)`
Sync the current branch with the remote, keeping all local changes intact.
The following steps are carried out: `stash`, `pull`, `push`, `stash pop`. If there were no changes to stash, the last `stash pop` is not executed.
* `remote` - `String` (defaults to `origin`).
* `branch` - `String` (defaults to `master`).
* `callback` - Receives `(err)`.
## Commit
### `Commit#id`
`String` - The commit's SHA.

View File

@ -1,5 +1,5 @@
{ "name": "gift"
, "version": "0.0.5"
, "version": "0.0.6"
, "description": "a Git wrapper library"
, "keywords": ["git"]
, "homepage": "https://github.com/sentientwaffle/gift"
@ -25,6 +25,7 @@
, "devDependencies":
{ "should": "1.2.x"
, "mocha": "1.x.x"
, "sinon": "1.6.x"
, "coffee-script": "1.6.x"
}

View File

@ -11,10 +11,28 @@ module.exports = Git = (path, bare=false) ->
# Public: Initialize a git repository.
#
# path - The directory to run `git init .` in.
# bare - Create a bare repository when true.
# callback - Receives `(err, repo)`.
#
Git.init = (path, callback) ->
exec "git init .", {cwd: path}
Git.init = (path, bare, callback) ->
[bare, callback] = [callback, bare] if !callback
if bare
bash = "git init --bare ."
else
bash = "git init ."
exec bash, {cwd: path}
, (err, stdout, stderr) ->
return callback err if err
return callback err, (new Repo path)
return callback err, (new Repo path, bare)
# Public: Clone a git repository.
#
# repository - The repository to clone from.
# path - The directory to clone into.
# callback - Receives `(err, repo)`.
#
Git.clone = (repository, path, callback) ->
bash = "git clone #{repository} #{path}"
exec bash, (err, stdout, stderr) ->
return callback err if err
return callback err, (new Repo path)

View File

@ -299,18 +299,26 @@ module.exports = class Repo
# Public: Sync the current branch with the remote.
#
# Arguments: ([[remote_name, ]branch_name, ]callback)
#
# remote_name - String (optional).
# branch_name - String.
# callback - Receives `(err)`.
#
sync: (remote_name, branch, callback) ->
[remote_name, callback, branch] = ['origin', branch, remote_name] if !callback
[remote_name, callback, branch] = ['origin', remote_name, []] if !branch
sync: (remote_name, branch_name, callback) ->
# handle 'curried' arguments
[remote, branch] = [remote_name, branch_name] if typeof callback is "function"
[remote, branch, callback] = ["origin", remote_name, branch_name] if typeof branch_name is "function"
[remote, branch, callback] = ["origin", "master", remote_name] if typeof remote_name is "function"
@status (err, status) =>
return callback err if err
@git "stash", {}, ["save"], (err) =>
return callback err if err
@git "pull", {}, [remote_name, branch], (err) =>
@git "pull", {}, [remote, branch], (err) =>
return callback err if err
@git "push", {}, [remote_name, branch], (err) =>
@git "push", {}, [remote, branch], (err) =>
return callback err if err
if not status?.clean
@git "stash", {}, ["pop"], (err) =>

View File

@ -1,10 +1,57 @@
should = require 'should'
git = require '../src'
Repo = require '../src/repo'
fs = require "fs"
{exec} = require 'child_process'
describe "git", ->
describe "()", ->
repo = git "#{__dirname}/fixtures/simple"
it "returns a Repo", ->
repo.should.be.an.instanceof Repo
describe "init()", ->
repo = null
newRepositoryDir = "#{__dirname}/fixtures/new"
before (done) ->
fs.mkdirSync newRepositoryDir
git.init newRepositoryDir, (err, _repo) ->
repo = _repo
done err
it "inits a Repo", ->
repo.should.be.an.instanceof Repo
bare = repo.bare || false
bare.should.be.false
after (done) ->
exec "rm -rf #{newRepositoryDir}", done
describe "init() bare", ->
repo = null
newRepositoryDir = "#{__dirname}/fixtures/bare"
before (done) ->
fs.mkdirSync newRepositoryDir
git.init newRepositoryDir, true, (err, _repo) ->
repo = _repo
done err
it "inits a bare Repo", ->
repo.should.be.an.instanceof Repo
bare = repo.bare || false
bare.should.be.true
after (done) ->
exec "rm -rf #{newRepositoryDir}", done
describe "clone()", ->
@timeout 30000
repo = null
newRepositoryDir = "#{__dirname}/fixtures/clone"
before (done) ->
git.clone "https://github.com/notatestuser/gift.git", newRepositoryDir, (err, _repo) ->
repo = _repo
done err
it "clone a repository", (done) ->
repo.should.be.an.instanceof Repo
repo.remote_list (err, remotes) ->
remotes.should.have.length 1
done()
after (done) ->
exec "rm -rf #{newRepositoryDir}", done

View File

@ -1,4 +1,5 @@
should = require 'should'
sinon = require 'sinon'
fs = require 'fs'
fixtures = require './fixtures'
git = require '../src'
@ -13,6 +14,43 @@ Status = require '../src/status'
{exec} = require 'child_process'
describe "Repo", ->
describe "#sync", ->
describe "when passed curried arguments", ->
repo = fixtures.branched
remote = branch = ""
before ->
sinon.stub repo, "git", (command, opts, args, callback) ->
if command is "pull"
remote = args[0]
branch = args[1]
callback? null
sinon.stub repo, "status", (callback) ->
callback? null, clean: no
after ->
repo.git.restore()
repo.status.restore()
it "passes through the correct parameters when nothing is omitted", (done) ->
repo.sync "github", "my-branch", ->
remote.should.eql "github"
branch.should.eql "my-branch"
done()
it "passes through the correct parameters when remote_name is omitted", (done) ->
repo.sync "my-branch", ->
remote.should.eql "origin"
branch.should.eql "my-branch"
done()
it "passes through the correct parameters when remote_name and branch are omitted", (done) ->
repo.sync ->
remote.should.eql "origin"
branch.should.eql "master"
done()
describe "#identify", ->
describe "when asked to set the identity's name and email", ->
repo = fixtures.branched
@ -235,10 +273,11 @@ describe "Repo", ->
git.init git_dir, (err) ->
return done err if err
repo = git(git_dir)
fs.writeFileSync "#{git_dir}/foo.txt", "cheese"
repo.add "#{git_dir}/foo.txt", (err) ->
return done err if err
repo.commit "initial commit", {all: true}, done
repo.identify new Actor('name', 'em@il'), ->
fs.writeFileSync "#{git_dir}/foo.txt", "cheese"
repo.add "#{git_dir}/foo.txt", (err) ->
return done err if err
repo.commit "initial commit", {all: true}, done
after (done) ->
exec "rm -rf #{ git_dir }", done