Skip to content

Commit

Permalink
Merge branch 'master' of github.com:sentientwaffle/gift
Browse files Browse the repository at this point in the history
* '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
  • Loading branch information
notatestuser committed Oct 12, 2013
2 parents dd96ffd + 05a6434 commit b600af2
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 16 deletions.
57 changes: 55 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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.

Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -25,6 +25,7 @@
, "devDependencies":
{ "should": "1.2.x"
, "mocha": "1.x.x"
, "sinon": "1.6.x"
, "coffee-script": "1.6.x"
}

Expand Down
24 changes: 21 additions & 3 deletions src/index.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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)
18 changes: 13 additions & 5 deletions src/repo.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down
49 changes: 48 additions & 1 deletion test/index.test.coffee
Original file line number Diff line number Diff line change
@@ -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
47 changes: 43 additions & 4 deletions test/repo.test.coffee
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
should = require 'should'
sinon = require 'sinon'
fs = require 'fs'
fixtures = require './fixtures'
git = require '../src'
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit b600af2

Please sign in to comment.