diff --git a/README.md b/README.md index 8bd6958..d4df787 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ A simple Node.js wrapper for the Git CLI. The API is based on # => # ## Repo -### Repo#path +### `Repo#path` `String` - The path to the repository. -### Repo#commits([treeish, [limit, [skip, ]]]callback) +### `Repo#commits([treeish, [limit, [skip, ]]]callback)` Get a list of commits. * `treeish` - `String` (optional). @@ -45,64 +45,64 @@ Skip some (for pagination): repo.commits "master", 30, 30, (err, commits) -> -### Repo#tree([treeish]) => Tree +### `Repo#tree([treeish]) => Tree` The `Tree` object for the treeish (which defaults to "master"). repo.tree().contents (err, children) -> for child in children console.log child.name -### Repo#diff(commitA, commitB, [paths, ]callback) +### `Repo#diff(commitA, commitB, [paths, ]callback)` Get the difference between the trees. The callback receives `(err, diffs)`. -### Repo#remotes(callback) +### `Repo#remotes(callback)` Get the repository's remotes. Receives `(err, remotes)`, where each remote is a Ref. -### Repo#remote_list(callback) +### `Repo#remote_list(callback)` Get a list of the repository's remote names. Get the string names of each of the remotes. -### Repo#remote_add(name, url, callback) +### `Repo#remote_add(name, url, callback)` Equivalent to `git remote add `. -### Repo#remote_fetch(name, callback) +### `Repo#remote_fetch(name, callback)` `git fetch ` -### Repo#status(callback) +### `Repo#status(callback)` The callback receives `(err, status)`. -### Repo#create_branch(name, callback) +### `Repo#create_branch(name, callback)` Create a new branch with `name`, and call the callback when complete with an error, if one occurred. -### Repo#delete_branch(name, callback) +### `Repo#delete_branch(name, callback)` Delete the branch `name`, and call the callback with an error, if one occurred. -### Repo#tags(callback) +### `Repo#tags(callback)` Get a list of `Tag`s. -### Repo#create_tag(name, callback) +### `Repo#create_tag(name, [options, ]callback)` Create a tab with the given name. -### Repo#delete_tag(name, callback) +### `Repo#delete_tag(name, callback)` Delete the tag with the given name. -### Repo#branches(callback) +### `Repo#branches(callback)` `callback` receives `(err, heads)`. -### Repo#create_branch(name, callback) +### `Repo#create_branch(name, callback)` Create a branch with the given name. -### Repo#delete_branch(delete, callback) +### `Repo#delete_branch(delete, callback)` Delete the branch with the given name. -### Repo#branch([branch, ]callback) +### `Repo#branch([branch, ]callback)` Get a branch. * `branch` - The name of the branch to get. Defaults to the @@ -110,7 +110,7 @@ Get a branch. * `callback` - Receives `(err, head)`. -### Repo#commit(message, [options, ]callback) +### `Repo#commit(message, [options, ]callback)` Commit some changes. * `message` - `String` @@ -119,66 +119,66 @@ Commit some changes. - `amend` - `Boolean` * `callback` - Receives `(err)`. -### Repo#add(files, callback) +### `Repo#add(files, callback)` `git add ` -### Repo#remove(files, callback) +### `Repo#remove(files, callback)` `git rm ` -### Repo#checkout(treeish, callback) +### `Repo#checkout(treeish, callback)` `git checkout ` ## Commit -### Commit#id +### `Commit#id` `String` - The commit's SHA. -### Commit#parents +### `Commit#parents` `Commit[]` -### Commit#tree(callback) +### `Commit#tree(callback)` * `callback` - Receives `(err, tree)`. -### Commit#author +### `Commit#author` `Actor` -### Commit#authored_date +### `Commit#authored_date` `Date` -### Commit#committer +### `Commit#committer` `Actor` -### Commit#committed_date +### `Commit#committed_date` `Date` -### Commit#message +### `Commit#message` `String` ## Head -### Head#name +### `Head#name` `String` -### Head#commit +### `Head#commit` `Commit` ## Tag -### Tag#name +### `Tag#name` `String` -### Tag#commit +### `Tag#commit` `Commit` -### Tag#message(callback) +### `Tag#message(callback)` The callback receives `(err, message)` (`message` is a String). -### Tag#tagger(callback) +### `Tag#tagger(callback)` The callback receives `(err, actor)`. -### Tag#tag_date(callback) +### `Tag#tag_date(callback)` The callback receives `(err, date)`. ## Status -### Status#clean +### `Status#clean` `Boolean` -### Status#files +### `Status#files` `Object` - The keys are files, the values objects indicating whether or not the file is staged, tracked, etc. @@ -189,63 +189,63 @@ Each file has the following properties: * `tracked` - `Boolean` ## Actor -### Actor#name +### `Actor#name` `String` -### Actor#email +### `Actor#email` `String` -### Actor#hash +### `Actor#hash` `String` - The MD5 hash of the actor's email. Useful for displaying [Gravatar](http://en.gravatar.com/) avatars. ## Tree -### Tree#id +### `Tree#id` `String` - SHA1 -### Tree#contents(callback) +### `Tree#contents(callback)` * `callback` - Receives `(err, children)`. * `children` - An array of `Blob`s, `Tree`s, and `Submodule`s. -### Tree#blobs(callback) +### `Tree#blobs(callback)` * `callback` - Receives `(err, child_blobs)`. * `children` - `[Blob]` -### Tree#trees(callback) +### `Tree#trees(callback)` * `callback` - Receives `(err, child_trees)`. * `children` - `[Tree]` -### Tree#find(directory, callback) +### `Tree#find(directory, callback)` * `directory` - `String` * `callback` - Receives `(err, thing)`. ## Blob -### Blob#id +### `Blob#id` `String` - SHA1 -### Blob#mode +### `Blob#mode` `String` -### Blob#data(callback) +### `Blob#data(callback)` * `callback` - `(err, data)` ## Submodule -### Submodule#id +### `Submodule#id` `String` -### Submodule#name +### `Submodule#name` `String` -### Submodule#mode +### `Submodule#mode` `String` -### Submodule#url(callback) +### `Submodule#url(callback)` Get the url the submodule points to. diff --git a/package.json b/package.json index a52867e..47fa1c8 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "name": "gift" -, "version": "0.0.2" +, "version": "0.0.5" , "description": "a Git wrapper library" , "keywords": ["git"] , "homepage": "https://github.com/sentientwaffle/gift" diff --git a/src/index.coffee b/src/index.coffee index 77d72c9..42ea7fb 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -14,7 +14,7 @@ module.exports = Git = (path, bare=false) -> # callback - Receives `(err, repo)`. # Git.init = (path, callback) -> - exec "git init .", {cwd: git_dir} + exec "git init .", {cwd: path} , (err, stdout, stderr) -> return callback err if err return callback err, (new Repo path) diff --git a/src/repo.coffee b/src/repo.coffee index cde4321..b0da307 100644 --- a/src/repo.coffee +++ b/src/repo.coffee @@ -125,7 +125,7 @@ module.exports = class Repo # Public: Get the repository's status (`git status`). # - # callback - Receives `(err, callback)` + # callback - Receives `(err, status)` # status: (callback) -> return Status(this, callback) @@ -141,10 +141,13 @@ module.exports = class Repo # Public: Create a tag. # # name - String + # options - An Object of command line arguments to pass to + # `git tag` (optional). # callback - Receives `(err)`. # - create_tag: (name, callback) -> - @git "tag", {a: name}, callback + create_tag: (name, options, callback) -> + [options, callback] = [callback, options] if !callback + @git "tag", options, [name], callback # Public: Delete the tag. # @@ -237,3 +240,19 @@ module.exports = class Repo # Public: Revert the given commit. revert: (sha, callback) -> @git "revert", {}, sha, callback + + + # Public: Sync the current branch with the remote. + # + # callback - Receives `(err)`. + # + sync: (callback) -> + @git "stash", {}, ["save"], (err) => + return callback err if err + @git "pull", {}, branch, (err) => + return callback err if err + @git "push", (err) => + return callback err if err + @git "stash", {}, "pop", (err) => + return callback err if err + return callback null diff --git a/src/status.coffee b/src/status.coffee index 169a816..0e35eaf 100644 --- a/src/status.coffee +++ b/src/status.coffee @@ -11,7 +11,10 @@ module.exports = S = (repo, callback) -> BEGIN_STAGED = "# Changes to be committed:" -BEGIN_UNSTAGED = "# Changed but not updated:" +BEGIN_UNSTAGED = [ + "# Changed but not updated:" + "# Changes not staged for commit:" +] BEGIN_UNTRACKED = "# Untracked files:" FILE = /^#\s+([^\s]+)[:]\s+(.+)$/ TYPES = @@ -28,13 +31,15 @@ S.Status = class Status @clean = true state = null for line in text.split("\n") - @clean = false if line == BEGIN_STAGED state = "staged" - else if line == BEGIN_UNSTAGED + @clean = false + else if ~BEGIN_UNSTAGED.indexOf(line) state = "unstaged" + @clean = false else if line == BEGIN_UNTRACKED state = "untracked" + @clean = false else if state && match = FILE.exec(line) file = match[2] data = switch state diff --git a/test/repo.test.coffee b/test/repo.test.coffee index 6295488..74da4b7 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -1,4 +1,5 @@ should = require 'should' +fs = require 'fs' fixtures = require './fixtures' git = require '../src' Commit = require '../src/commit' @@ -8,6 +9,7 @@ Tag = require '../src/tag' Status = require '../src/status' {Ref, Head} = require '../src/ref' +{exec} = require 'child_process' describe "Repo", -> describe "#commits", -> @@ -199,6 +201,25 @@ describe "Repo", -> tags.should.eql [] done err + describe "#create_tag", -> + repo = null + git_dir = __dirname + "/fixtures/junk_create_tag" + before (done) -> + fs.mkdir git_dir, 0755, (err) -> + return done err if err + 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 + + after (done) -> + exec "rm -rf #{ git_dir }", done + + it "creates a tag", (done) -> + repo.create_tag "foo", done describe "#delete_tag", -> describe "deleting a tag that does not exist", -> diff --git a/test/status.test.coffee b/test/status.test.coffee index d568e84..b1c5b6d 100644 --- a/test/status.test.coffee +++ b/test/status.test.coffee @@ -22,9 +22,39 @@ GIT_STATUS = """ # # pickles.txt """ +GIT_STATUS_CLEAN = """ + # On branch master + # nothing to commit (working directory clean) + """ +GIT_STATUS_NOT_CLEAN = """ + # On branch master + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: lib/index.js + # modified: npm-shrinkwrap.json + # modified: package.json + # + """ describe "Status", -> describe "()", -> + describe "when there are no changes", -> + repo = fixtures.status + status = new Status.Status repo + status.parse GIT_STATUS_CLEAN + + it "is clean", -> + status.clean.should.be.true + + describe "when there are changes", -> + repo = fixtures.status + status = new Status.Status repo + status.parse GIT_STATUS_NOT_CLEAN + it "is not clean", -> + status.clean.should.be.false + describe "when there are changes", -> repo = fixtures.status status = new Status.Status repo