From b1d4cdfd594b362843170fab486c02d3c4b2d089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 18:27:38 +0200 Subject: [PATCH 01/20] Add repo.checkoutFile --- src/repo.coffee | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/repo.coffee b/src/repo.coffee index 16d8541..b5647d6 100644 --- a/src/repo.coffee +++ b/src/repo.coffee @@ -73,7 +73,7 @@ module.exports = class Repo # # # Skip some (for pagination): # repo.commits "master", 30, 30, (err, commits) -> - # + # # # Do not limit commits amount # repo.commits "master", -1, (err, commits) -> # @@ -93,10 +93,10 @@ module.exports = class Repo Commit.find_all this, start, options, callback - # Internal: Returns current commit id - # + # Internal: Returns current commit id + # # callback - Receives `(err, id)`. - # + # current_commit_id: (callback) -> @git "rev-parse HEAD", {}, [] , (err, stdout, stderr) => @@ -104,10 +104,10 @@ module.exports = class Repo return callback null, _.first stdout.split "\n" - # Public: - # + # Public: + # # callback - Receives `(err, commit)` - # + # current_commit: (callback) -> @current_commit_id (err, commit_id) => return callback err if err @@ -241,7 +241,7 @@ module.exports = class Repo status: (callback) -> return Status(this, callback) - # Public: Show information about files in the index and the + # Public: Show information about files in the index and the # working tree. # # options - An Object of command line arguments to pass to @@ -333,6 +333,19 @@ module.exports = class Repo checkout: (treeish, callback) -> @git "checkout", {}, treeish, callback + # Public: Checkout file(s) to the index + # + # files - Array of String paths; or a String path. If you want to + # checkout all files pass '.'. + # options - Object (optional). + # "force" - Boolean + # callback - Receives `(err)`. + # + checkoutFile: (files, options, callback) -> + [options, callback] = [callback, options] if !callback + options ?= {} + files = [files] if _.isString files + @git "checkout", options, _.flatten['--', files], callback # Public: Commit some code. # @@ -357,13 +370,13 @@ module.exports = class Repo # options - Object (optional). # "all" - Boolean # callback - Receives `(err)`. - # + # add: (files, options, callback) -> [options, callback] = [callback, options] if !callback options ?= {} files = [files] if _.isString files @git "add", options, files, callback - + # Public: Remove files from the index. # # files - Array of String paths; or a String path. @@ -411,7 +424,7 @@ module.exports = class Repo return callback null else return callback null - + # Public: Pull the remotes from the master. # # Arguments: ([[remote_name, ]branch_name, ]callback) @@ -432,9 +445,9 @@ module.exports = class Repo @git "pull", {}, [remote, branch], (err, stdout, stderr) => return callback stderr if err return callback null - + # Internal: Parse the list of files from `git ls-files` - # + # # Return Files[] parse_lsFiles: (text,options) -> files = [] From cee0e3aeb0e3c47190713c67dcccfca880e00e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 19:04:22 +0200 Subject: [PATCH 02/20] Add repo.reset --- src/repo.coffee | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/repo.coffee b/src/repo.coffee index b5647d6..22e1983 100644 --- a/src/repo.coffee +++ b/src/repo.coffee @@ -333,17 +333,40 @@ module.exports = class Repo checkout: (treeish, callback) -> @git "checkout", {}, treeish, callback + # Public: Reset the git repo. + # + # treeish - The {String} to reset to. + # options - The {object} containing one of the following items: + # :soft - {Boolean) + # :mixed - {Boolean) + # :hard - {Boolean) + # :merge - {Boolean) + # :keep - {Boolean) + # callback - The {Function} to callback. + # + reset: (treeish, options, callback) -> + [options, callback] = [callback, options] if !callback + [treeish, callback] = [callback, treeish] if !callback + [treeish, options] = [options, treeish] if typeof treeish is 'object' + treeish ?= 'HEAD' + options ?= {} + + @git "reset", options, treeish, callback + # Public: Checkout file(s) to the index # # files - Array of String paths; or a String path. If you want to - # checkout all files pass '.'. + # checkout all files pass '.'.' # options - Object (optional). # "force" - Boolean # callback - Receives `(err)`. # checkoutFile: (files, options, callback) -> [options, callback] = [callback, options] if !callback + [files, callback] = [callback, files] if !callback + [files, options] = [options, files] if typeof files is 'object' options ?= {} + files ?= '.' files = [files] if _.isString files @git "checkout", options, _.flatten['--', files], callback From 7e778ec1aaa99cbdf0fdfa3a819fc7523528ffa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 19:16:58 +0200 Subject: [PATCH 03/20] Add fixtures for reset test --- test/fixtures/reset/COMMIT_EDITMSG | 1 + test/fixtures/reset/HEAD | 1 + test/fixtures/reset/ORIG_HEAD | 1 + test/fixtures/reset/config | 5 + test/fixtures/reset/description | 1 + .../reset/hooks/applypatch-msg.sample | 15 ++ test/fixtures/reset/hooks/commit-msg.sample | 24 +++ test/fixtures/reset/hooks/post-update.sample | 8 + .../reset/hooks/pre-applypatch.sample | 14 ++ test/fixtures/reset/hooks/pre-commit.sample | 49 +++++ test/fixtures/reset/hooks/pre-push.sample | 54 ++++++ test/fixtures/reset/hooks/pre-rebase.sample | 169 ++++++++++++++++++ .../reset/hooks/prepare-commit-msg.sample | 36 ++++ test/fixtures/reset/hooks/update.sample | 128 +++++++++++++ test/fixtures/reset/index | Bin 0 -> 334 bytes test/fixtures/reset/info/exclude | 6 + test/fixtures/reset/info/refs | 2 + test/fixtures/reset/logs/HEAD | 12 ++ .../reset/logs/refs/heads/f-gitCheckoutFiles | 2 + test/fixtures/reset/logs/refs/heads/master | 4 + .../14/e5a1a3a459e05d486b98df2802ee4b30c33995 | Bin 0 -> 194 bytes .../41/2d321c36a34331125a77493b5dd41f5313a568 | Bin 0 -> 295 bytes .../55/80d8a9feeadf1c36a73a2778c62206314aebac | Bin 0 -> 28 bytes .../56/02c1d7079f5ff3f49f341722c6d5baf93bb26e | 3 + .../c2/dfadf4d76bea7fbe28086d95aa0c803237539e | Bin 0 -> 21 bytes test/fixtures/reset/objects/info/packs | 2 + ...f08ce8f755306c59b6d804345abf334b5586f8.idx | Bin 0 -> 1408 bytes ...08ce8f755306c59b6d804345abf334b5586f8.pack | Bin 0 -> 1499 bytes test/fixtures/reset/packed-refs | 3 + 29 files changed, 540 insertions(+) create mode 100644 test/fixtures/reset/COMMIT_EDITMSG create mode 100644 test/fixtures/reset/HEAD create mode 100644 test/fixtures/reset/ORIG_HEAD create mode 100644 test/fixtures/reset/config create mode 100644 test/fixtures/reset/description create mode 100755 test/fixtures/reset/hooks/applypatch-msg.sample create mode 100755 test/fixtures/reset/hooks/commit-msg.sample create mode 100755 test/fixtures/reset/hooks/post-update.sample create mode 100755 test/fixtures/reset/hooks/pre-applypatch.sample create mode 100755 test/fixtures/reset/hooks/pre-commit.sample create mode 100755 test/fixtures/reset/hooks/pre-push.sample create mode 100755 test/fixtures/reset/hooks/pre-rebase.sample create mode 100755 test/fixtures/reset/hooks/prepare-commit-msg.sample create mode 100755 test/fixtures/reset/hooks/update.sample create mode 100644 test/fixtures/reset/index create mode 100644 test/fixtures/reset/info/exclude create mode 100644 test/fixtures/reset/info/refs create mode 100644 test/fixtures/reset/logs/HEAD create mode 100644 test/fixtures/reset/logs/refs/heads/f-gitCheckoutFiles create mode 100644 test/fixtures/reset/logs/refs/heads/master create mode 100644 test/fixtures/reset/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 create mode 100644 test/fixtures/reset/objects/41/2d321c36a34331125a77493b5dd41f5313a568 create mode 100644 test/fixtures/reset/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac create mode 100644 test/fixtures/reset/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e create mode 100644 test/fixtures/reset/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e create mode 100644 test/fixtures/reset/objects/info/packs create mode 100644 test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx create mode 100644 test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack create mode 100644 test/fixtures/reset/packed-refs diff --git a/test/fixtures/reset/COMMIT_EDITMSG b/test/fixtures/reset/COMMIT_EDITMSG new file mode 100644 index 0000000..406ba8c --- /dev/null +++ b/test/fixtures/reset/COMMIT_EDITMSG @@ -0,0 +1 @@ +Second commit. diff --git a/test/fixtures/reset/HEAD b/test/fixtures/reset/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/test/fixtures/reset/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/test/fixtures/reset/ORIG_HEAD b/test/fixtures/reset/ORIG_HEAD new file mode 100644 index 0000000..e2759dd --- /dev/null +++ b/test/fixtures/reset/ORIG_HEAD @@ -0,0 +1 @@ +2bef842346e4511c21c592fda70dd45b1dcac863 diff --git a/test/fixtures/reset/config b/test/fixtures/reset/config new file mode 100644 index 0000000..515f483 --- /dev/null +++ b/test/fixtures/reset/config @@ -0,0 +1,5 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true diff --git a/test/fixtures/reset/description b/test/fixtures/reset/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/test/fixtures/reset/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/test/fixtures/reset/hooks/applypatch-msg.sample b/test/fixtures/reset/hooks/applypatch-msg.sample new file mode 100755 index 0000000..8b2a2fe --- /dev/null +++ b/test/fixtures/reset/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +test -x "$GIT_DIR/hooks/commit-msg" && + exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} +: diff --git a/test/fixtures/reset/hooks/commit-msg.sample b/test/fixtures/reset/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/test/fixtures/reset/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/test/fixtures/reset/hooks/post-update.sample b/test/fixtures/reset/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/test/fixtures/reset/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/test/fixtures/reset/hooks/pre-applypatch.sample b/test/fixtures/reset/hooks/pre-applypatch.sample new file mode 100755 index 0000000..b1f187c --- /dev/null +++ b/test/fixtures/reset/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} +: diff --git a/test/fixtures/reset/hooks/pre-commit.sample b/test/fixtures/reset/hooks/pre-commit.sample new file mode 100755 index 0000000..68d62d5 --- /dev/null +++ b/test/fixtures/reset/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/test/fixtures/reset/hooks/pre-push.sample b/test/fixtures/reset/hooks/pre-push.sample new file mode 100755 index 0000000..1f3bceb --- /dev/null +++ b/test/fixtures/reset/hooks/pre-push.sample @@ -0,0 +1,54 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +z40=0000000000000000000000000000000000000000 + +IFS=' ' +while read local_ref local_sha remote_ref remote_sha +do + if [ "$local_sha" = $z40 ] + then + # Handle delete + : + else + if [ "$remote_sha" = $z40 ] + then + # New branch, examine all commits + range="$local_sha" + else + # Update to existing branch, examine new commits + range="$remote_sha..$local_sha" + fi + + # Check for WIP commit + commit=`git rev-list -n 1 --grep '^WIP' "$range"` + if [ -n "$commit" ] + then + echo "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/test/fixtures/reset/hooks/pre-rebase.sample b/test/fixtures/reset/hooks/pre-rebase.sample new file mode 100755 index 0000000..33730ca --- /dev/null +++ b/test/fixtures/reset/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up-to-date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/test/fixtures/reset/hooks/prepare-commit-msg.sample b/test/fixtures/reset/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..f093a02 --- /dev/null +++ b/test/fixtures/reset/hooks/prepare-commit-msg.sample @@ -0,0 +1,36 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first comments out the +# "Conflicts:" part of a merge commit. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +case "$2,$3" in + merge,) + /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; + +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$1" ;; + + *) ;; +esac + +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/test/fixtures/reset/hooks/update.sample b/test/fixtures/reset/hooks/update.sample new file mode 100755 index 0000000..d847583 --- /dev/null +++ b/test/fixtures/reset/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to blocks unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --bool hooks.allowunannotated) +allowdeletebranch=$(git config --bool hooks.allowdeletebranch) +denycreatebranch=$(git config --bool hooks.denycreatebranch) +allowdeletetag=$(git config --bool hooks.allowdeletetag) +allowmodifytag=$(git config --bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero="0000000000000000000000000000000000000000" +if [ "$newrev" = "$zero" ]; then + newrev_type=delete +else + newrev_type=$(git cat-file -t $newrev) +fi + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annotated tag + short_refname=${refname##refs/tags/} + if [ "$allowunannotated" != "true" ]; then + echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/test/fixtures/reset/index b/test/fixtures/reset/index new file mode 100644 index 0000000000000000000000000000000000000000..54b94a986956a960d700fec1a52909e4bedd94b6 GIT binary patch literal 334 zcmZ?q402{*U|<4bmf*!a5BQFW!D*nFB*Ph&X$%aFOBfiKUqCS9Jl<`wms~SH{@LX8 z?QRKIc70DyjTQq(qF!=-T3Tu<0|Rz*Sou)RVc2bwd}Qt>rP(oaikiNk<(ewR>ic#A z14j}8b6CEin#0WAY+ALu;h=8I>UrC|3RB7y3@$|8Wnf9s%PI!?00@E?OO*@zTx^HY zKp~*NSVd9IVPHFSf9;p+*{|yNX>jCDUB%O2WF9<^fuks~yhyL4qJ)7VB*@hjsF#gF e*HFQLYvukoC)UJ$<5P)fSFw0>?%1lXZ7%@g8f)SJ literal 0 HcmV?d00001 diff --git a/test/fixtures/reset/info/exclude b/test/fixtures/reset/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/test/fixtures/reset/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/test/fixtures/reset/info/refs b/test/fixtures/reset/info/refs new file mode 100644 index 0000000..6f80955 --- /dev/null +++ b/test/fixtures/reset/info/refs @@ -0,0 +1,2 @@ +40216d142a8bf81e327f510990f2357dfd404486 refs/heads/f-gitCheckoutFiles +bdc76865cfc1d089ee4e238035a5860357c36506 refs/heads/master diff --git a/test/fixtures/reset/logs/HEAD b/test/fixtures/reset/logs/HEAD new file mode 100644 index 0000000..bd84dd9 --- /dev/null +++ b/test/fixtures/reset/logs/HEAD @@ -0,0 +1,12 @@ +0000000000000000000000000000000000000000 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1402436637 +0200 commit (initial): Initial commit +b54f2aa124bb81b547fa5b2cf57caf23076d85ff b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192551 +0200 checkout: moving from master to master +b54f2aa124bb81b547fa5b2cf57caf23076d85ff b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192582 +0200 checkout: moving from master to f-gitCheckoutFiles +b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192722 +0200 commit: lol +40216d142a8bf81e327f510990f2357dfd404486 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192725 +0200 checkout: moving from f-gitCheckoutFiles to master +b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192736 +0200 checkout: moving from master to f-gitCheckoutFiles +40216d142a8bf81e327f510990f2357dfd404486 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192748 +0200 checkout: moving from f-gitCheckoutFiles to master +b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192813 +0200 checkout: moving from master to f-gitCheckoutFiles +40216d142a8bf81e327f510990f2357dfd404486 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192822 +0200 checkout: moving from f-gitCheckoutFiles to master +b54f2aa124bb81b547fa5b2cf57caf23076d85ff 2bef842346e4511c21c592fda70dd45b1dcac863 Maximilian Schüßler 1403194884 +0200 commit: LOL +2bef842346e4511c21c592fda70dd45b1dcac863 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403198029 +0200 reset: moving to HEAD~1 +b54f2aa124bb81b547fa5b2cf57caf23076d85ff bdc76865cfc1d089ee4e238035a5860357c36506 Maximilian Schüßler 1403198059 +0200 commit: Second commit. diff --git a/test/fixtures/reset/logs/refs/heads/f-gitCheckoutFiles b/test/fixtures/reset/logs/refs/heads/f-gitCheckoutFiles new file mode 100644 index 0000000..922497b --- /dev/null +++ b/test/fixtures/reset/logs/refs/heads/f-gitCheckoutFiles @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192582 +0200 branch: Created from HEAD +b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192722 +0200 commit: lol diff --git a/test/fixtures/reset/logs/refs/heads/master b/test/fixtures/reset/logs/refs/heads/master new file mode 100644 index 0000000..a8c5951 --- /dev/null +++ b/test/fixtures/reset/logs/refs/heads/master @@ -0,0 +1,4 @@ +0000000000000000000000000000000000000000 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1402436637 +0200 commit (initial): Initial commit +b54f2aa124bb81b547fa5b2cf57caf23076d85ff 2bef842346e4511c21c592fda70dd45b1dcac863 Maximilian Schüßler 1403194884 +0200 commit: LOL +2bef842346e4511c21c592fda70dd45b1dcac863 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403198029 +0200 reset: moving to HEAD~1 +b54f2aa124bb81b547fa5b2cf57caf23076d85ff bdc76865cfc1d089ee4e238035a5860357c36506 Maximilian Schüßler 1403198059 +0200 commit: Second commit. diff --git a/test/fixtures/reset/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 b/test/fixtures/reset/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 new file mode 100644 index 0000000000000000000000000000000000000000..7ca6048e91ec922d64d4dcd7f42bb29cca55f2d0 GIT binary patch literal 194 zcmV;z06qVB0TqtHN&`UP=VOBxkVav&@UoBTZzr?tY7hZj0UilPJyFzNj}{C|JE*;N0%Et?S>XCH}4G9{_7h|A0SdPXGV_ literal 0 HcmV?d00001 diff --git a/test/fixtures/reset/objects/41/2d321c36a34331125a77493b5dd41f5313a568 b/test/fixtures/reset/objects/41/2d321c36a34331125a77493b5dd41f5313a568 new file mode 100644 index 0000000000000000000000000000000000000000..e4969ec0e6f49449e76e9d9024f3afb3f4c3076d GIT binary patch literal 295 zcmV+?0oeX{0bP+nPs1<_g*oR}Jhlr%T?M1NR2pbPAaOt(I3f;h=dnPWbdI}~e^1

K3Jic33p`7828?-tXS{D zFTB7so58Me!j*gMTy@04wkud?T=Wx6Z_(oty)sMY;ycc%ZIIZ0yG}4maFZZQFn?F# zrTnByBGMGH!NLISz2s5fb1bA`%Mxpc1^F??Le-U|(4U1z5yRfswk~ui7u6tZZ=EAf zz@5gBrm5lqV+tQ+$?08?!TH~;_u literal 0 HcmV?d00001 diff --git a/test/fixtures/reset/objects/info/packs b/test/fixtures/reset/objects/info/packs new file mode 100644 index 0000000..e1c1d46 --- /dev/null +++ b/test/fixtures/reset/objects/info/packs @@ -0,0 +1,2 @@ +P pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack + diff --git a/test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx b/test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx new file mode 100644 index 0000000000000000000000000000000000000000..dd0977380a84cc287d2311f819e957b0f4676e9f GIT binary patch literal 1408 zcmexg;-AdGz`z8=^r4?oan$3;}a{%Rr0_Fs| z6CdUR%EK@>kUbbN571pS$GqEOFS%xZ{IkjF+uahb?E0RZ8ZGVjEy`|B0%a7BPWro? z_e!+vsT0X2$w%gHQkoqzr>N=sS+1#4tiEq2I4I_dXm$UPGpY~dobbuC_OF9WTaHK) zV}QQ2Y=H9hl=}}A8p z4^ID9KiI?3z3$_d)kiACyBU0wm}S2I%iZ>qd8@zHLY3W(Tit&}>wK+Qugsp?`hV~7 zjMVc7FLb{1Q*JO_+QuAyIF;>y8h?3g@cG}xCuKhH+c-azwA+65+1y97H(k8u?A@)o zt~~0-p(j1T6MbC@YadV9VYpW?^j>M>NB8`T6IOqm*|C{lExYmC&pfTgPWc-{Qm+Lu49I>0%!1p2xDv>>fW#AP8<4-Q;6u-g@1X`c mk=t&tm_+S2_6}|P5hoyI_km6H+r_9y-cBcuw*I|0LmvQe{jaG2 literal 0 HcmV?d00001 diff --git a/test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack b/test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack new file mode 100644 index 0000000000000000000000000000000000000000..8fdeedee7bb520ddaf3d34347fb5ba936f2b8b79 GIT binary patch literal 1499 zcmV<11tj`VK|@Ob00062000b^5O|!ej7ti_FcbjyIYstD$xHKTLBtEV>Iq(w7h7l= zNmKAPUc_B5WlR#75? zRL*s9n2o5N^if-nQMSUG(CHW%ZgtFs-|#u5X`XQ5gCFC(Ql$xrL zY+z(&kY;Xfnqq34oR*ekZk%jsn4D%{kY=20Vw`GdXlb09WS(L=QMZuA#KOX4;vz2r z5UrqXU}Rvx#pUDg!vz3`mK7xL0a$pP`@{H$al$+nBXc98iHp1hK(vCkfsug$7gtVx z4i^BVWeCQX4S1Zb%rOeWFcbjLJ*W7)AV2xFNkNLMgOevnldlOR4Wub}8!zJ4izx`6 z!1WEURc0_94F`jR*At=a4QlBcaNgo{1|Q z^N&w?abe|U`S`xn`v|f_)luJ*h8-$I;Y!Z2HU7^g&U0+hCiu4E4HOMX0jvmkoHH~q zFf%bxNYqQtPfJTpW#HWwd&xEPwm?R&WyGdzw%$%a8 z?`OHDO0oLBod8vnqL)?7&}>?@yWya2%j$XCyb4pw6bvpz-i68+C6*WIl~j~4bg%ok zW%ZE?@oom+BxafK|8lqeWCj4p+c)sO8F-vskTFlgKn#WV`xTFNp(u?+C`+V(Dg+V( zVqioJNpR^w;!AxO8vZ@!G*qaQb@q3D&u@;k_x6KZ;*cBe+lmB0fmLQ)*Ew$k#aED? zjG5!k@w*Myu|L8Ema7bQgFjrkho0*R^Sizj-ElrFu)M*53k=GvMarKDG}ebWe!WbP zCAdnkN^t$A#B=pYb%;n?hAj#Mh;t#2{+?nZ^*af%cM!;@8XI+AkwX6jCljOYOV^aT zRLXj^wYSV938dHR(=^p@aZe|f15U=e;eLpgiEGMD*^mUx9`VJrhYe>lje?qQ>u--o zqIPX3v?cb3Ow^%QZ9Od27h;;&I2o&DXebNw3kVy3AG-^9oK23w3c@fDMDO{EVNZ%w zuz0m#y(oC|;5nF$hJ+T9EvR4bVq55K*qQg(XSR-Uz^cgLxRW)i#sI-%I&As<;FL7o z`y90b=(r&boC+_8eYBsO4Br1oi$Zc>cedFAWeu$JX7G(=ZW+&%a!Hcd0Ufp1m6MHT z=NM^(^G3rNp5Tm;SdCay{}G2VhZhbL4zDW&Xb=QKR@1mCe4rz@2jhr&>@aEV6KGT z;t+40&UsZT#cnuu^947#P@#attog$$MM#q-wN9i#Q<#E@ZZcHP)braP%i#t{4g z3HR`HG Date: Thu, 19 Jun 2014 19:45:55 +0200 Subject: [PATCH 04/20] Typo --- src/repo.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/repo.coffee b/src/repo.coffee index 22e1983..064a3ff 100644 --- a/src/repo.coffee +++ b/src/repo.coffee @@ -338,7 +338,7 @@ module.exports = class Repo # treeish - The {String} to reset to. # options - The {object} containing one of the following items: # :soft - {Boolean) - # :mixed - {Boolean) + # :mixed - {Boolean) When no other option given git defaults to 'mixed'. # :hard - {Boolean) # :merge - {Boolean) # :keep - {Boolean) @@ -368,7 +368,7 @@ module.exports = class Repo options ?= {} files ?= '.' files = [files] if _.isString files - @git "checkout", options, _.flatten['--', files], callback + @git "checkout", options, _.flatten ['--', files], callback # Public: Commit some code. # From cfc8c9c2567144c56b59eb20b8163450c6db550e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:11:08 +0200 Subject: [PATCH 05/20] Move fixtures/reset --- test/fixtures/reset/a.coffee | 28 +++++++++++ test/fixtures/reset/b.coffee | 9 ++++ test/fixtures/reset/d.js | 44 ++++++++++++++++++ .../reset/{ => git.git}/COMMIT_EDITMSG | 0 test/fixtures/reset/{ => git.git}/HEAD | 0 test/fixtures/reset/{ => git.git}/ORIG_HEAD | 0 test/fixtures/reset/{ => git.git}/config | 0 test/fixtures/reset/{ => git.git}/description | 0 .../{ => git.git}/hooks/applypatch-msg.sample | 0 .../{ => git.git}/hooks/commit-msg.sample | 0 .../{ => git.git}/hooks/post-update.sample | 0 .../{ => git.git}/hooks/pre-applypatch.sample | 0 .../{ => git.git}/hooks/pre-commit.sample | 0 .../reset/{ => git.git}/hooks/pre-push.sample | 0 .../{ => git.git}/hooks/pre-rebase.sample | 0 .../hooks/prepare-commit-msg.sample | 0 .../reset/{ => git.git}/hooks/update.sample | 0 test/fixtures/reset/{ => git.git}/index | Bin .../fixtures/reset/{ => git.git}/info/exclude | 0 test/fixtures/reset/{ => git.git}/info/refs | 0 test/fixtures/reset/{ => git.git}/logs/HEAD | 0 .../logs/refs/heads/f-gitCheckoutFiles | 0 .../{ => git.git}/logs/refs/heads/master | 0 .../14/e5a1a3a459e05d486b98df2802ee4b30c33995 | Bin .../41/2d321c36a34331125a77493b5dd41f5313a568 | Bin .../55/80d8a9feeadf1c36a73a2778c62206314aebac | Bin .../56/02c1d7079f5ff3f49f341722c6d5baf93bb26e | 0 .../c2/dfadf4d76bea7fbe28086d95aa0c803237539e | Bin .../reset/{ => git.git}/objects/info/packs | 0 ...f08ce8f755306c59b6d804345abf334b5586f8.idx | Bin ...08ce8f755306c59b6d804345abf334b5586f8.pack | Bin test/fixtures/reset/{ => git.git}/packed-refs | 0 test/fixtures/reset/rawr.txt | 1 + 33 files changed, 82 insertions(+) create mode 100644 test/fixtures/reset/a.coffee create mode 100644 test/fixtures/reset/b.coffee create mode 100644 test/fixtures/reset/d.js rename test/fixtures/reset/{ => git.git}/COMMIT_EDITMSG (100%) rename test/fixtures/reset/{ => git.git}/HEAD (100%) rename test/fixtures/reset/{ => git.git}/ORIG_HEAD (100%) rename test/fixtures/reset/{ => git.git}/config (100%) rename test/fixtures/reset/{ => git.git}/description (100%) rename test/fixtures/reset/{ => git.git}/hooks/applypatch-msg.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/commit-msg.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/post-update.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/pre-applypatch.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/pre-commit.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/pre-push.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/pre-rebase.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/prepare-commit-msg.sample (100%) rename test/fixtures/reset/{ => git.git}/hooks/update.sample (100%) rename test/fixtures/reset/{ => git.git}/index (100%) rename test/fixtures/reset/{ => git.git}/info/exclude (100%) rename test/fixtures/reset/{ => git.git}/info/refs (100%) rename test/fixtures/reset/{ => git.git}/logs/HEAD (100%) rename test/fixtures/reset/{ => git.git}/logs/refs/heads/f-gitCheckoutFiles (100%) rename test/fixtures/reset/{ => git.git}/logs/refs/heads/master (100%) rename test/fixtures/reset/{ => git.git}/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 (100%) rename test/fixtures/reset/{ => git.git}/objects/41/2d321c36a34331125a77493b5dd41f5313a568 (100%) rename test/fixtures/reset/{ => git.git}/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac (100%) rename test/fixtures/reset/{ => git.git}/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e (100%) rename test/fixtures/reset/{ => git.git}/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e (100%) rename test/fixtures/reset/{ => git.git}/objects/info/packs (100%) rename test/fixtures/reset/{ => git.git}/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx (100%) rename test/fixtures/reset/{ => git.git}/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack (100%) rename test/fixtures/reset/{ => git.git}/packed-refs (100%) create mode 100644 test/fixtures/reset/rawr.txt diff --git a/test/fixtures/reset/a.coffee b/test/fixtures/reset/a.coffee new file mode 100644 index 0000000..0db65dd --- /dev/null +++ b/test/fixtures/reset/a.coffee @@ -0,0 +1,28 @@ +# Assignment: +number = 42 +opposite = true + +# Conditions: +number = -42 if opposite + +# Functions: +square = (x) -> x * x + +# Arrays: +list = [1, 2, 3, 4, 5] + +# Objects: +math = + root: Math.sqrt + square: square + cube: (x) -> x * square x + +# Splats: +race = (winner, runners...) -> + print winner, runners + +# Existence: +alert "I knew it!" if elvis? + +# Array comprehensions: +cubes = (math.cube num for num in list) diff --git a/test/fixtures/reset/b.coffee b/test/fixtures/reset/b.coffee new file mode 100644 index 0000000..3463c49 --- /dev/null +++ b/test/fixtures/reset/b.coffee @@ -0,0 +1,9 @@ +grade = (student) -> + if student.excellentWork + "A+" + else if student.okayStuff + if student.triedHard then "B" else "B-" + else + "C" + +eldest = if 24 > 21 then "Liz" else "Ike" diff --git a/test/fixtures/reset/d.js b/test/fixtures/reset/d.js new file mode 100644 index 0000000..83357ab --- /dev/null +++ b/test/fixtures/reset/d.js @@ -0,0 +1,44 @@ +var cubes, list, math, num, number, opposite, race, square, + __slice = [].slice; + +number = 42; + +opposite = true; + +if (opposite) { + number = -42; +} + +square = function(x) { + return x * x; +}; + +list = [1, 2, 3, 4, 5]; + +math = { + root: Math.sqrt, + square: square, + cube: function(x) { + return x * square(x); + } +}; + +race = function() { + var runners, winner; + winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + return print(winner, runners); +}; + +if (typeof elvis !== "undefined" && elvis !== null) { + alert("I knew it!"); +} + +cubes = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = list.length; _i < _len; _i++) { + num = list[_i]; + _results.push(math.cube(num)); + } + return _results; +})(); diff --git a/test/fixtures/reset/COMMIT_EDITMSG b/test/fixtures/reset/git.git/COMMIT_EDITMSG similarity index 100% rename from test/fixtures/reset/COMMIT_EDITMSG rename to test/fixtures/reset/git.git/COMMIT_EDITMSG diff --git a/test/fixtures/reset/HEAD b/test/fixtures/reset/git.git/HEAD similarity index 100% rename from test/fixtures/reset/HEAD rename to test/fixtures/reset/git.git/HEAD diff --git a/test/fixtures/reset/ORIG_HEAD b/test/fixtures/reset/git.git/ORIG_HEAD similarity index 100% rename from test/fixtures/reset/ORIG_HEAD rename to test/fixtures/reset/git.git/ORIG_HEAD diff --git a/test/fixtures/reset/config b/test/fixtures/reset/git.git/config similarity index 100% rename from test/fixtures/reset/config rename to test/fixtures/reset/git.git/config diff --git a/test/fixtures/reset/description b/test/fixtures/reset/git.git/description similarity index 100% rename from test/fixtures/reset/description rename to test/fixtures/reset/git.git/description diff --git a/test/fixtures/reset/hooks/applypatch-msg.sample b/test/fixtures/reset/git.git/hooks/applypatch-msg.sample similarity index 100% rename from test/fixtures/reset/hooks/applypatch-msg.sample rename to test/fixtures/reset/git.git/hooks/applypatch-msg.sample diff --git a/test/fixtures/reset/hooks/commit-msg.sample b/test/fixtures/reset/git.git/hooks/commit-msg.sample similarity index 100% rename from test/fixtures/reset/hooks/commit-msg.sample rename to test/fixtures/reset/git.git/hooks/commit-msg.sample diff --git a/test/fixtures/reset/hooks/post-update.sample b/test/fixtures/reset/git.git/hooks/post-update.sample similarity index 100% rename from test/fixtures/reset/hooks/post-update.sample rename to test/fixtures/reset/git.git/hooks/post-update.sample diff --git a/test/fixtures/reset/hooks/pre-applypatch.sample b/test/fixtures/reset/git.git/hooks/pre-applypatch.sample similarity index 100% rename from test/fixtures/reset/hooks/pre-applypatch.sample rename to test/fixtures/reset/git.git/hooks/pre-applypatch.sample diff --git a/test/fixtures/reset/hooks/pre-commit.sample b/test/fixtures/reset/git.git/hooks/pre-commit.sample similarity index 100% rename from test/fixtures/reset/hooks/pre-commit.sample rename to test/fixtures/reset/git.git/hooks/pre-commit.sample diff --git a/test/fixtures/reset/hooks/pre-push.sample b/test/fixtures/reset/git.git/hooks/pre-push.sample similarity index 100% rename from test/fixtures/reset/hooks/pre-push.sample rename to test/fixtures/reset/git.git/hooks/pre-push.sample diff --git a/test/fixtures/reset/hooks/pre-rebase.sample b/test/fixtures/reset/git.git/hooks/pre-rebase.sample similarity index 100% rename from test/fixtures/reset/hooks/pre-rebase.sample rename to test/fixtures/reset/git.git/hooks/pre-rebase.sample diff --git a/test/fixtures/reset/hooks/prepare-commit-msg.sample b/test/fixtures/reset/git.git/hooks/prepare-commit-msg.sample similarity index 100% rename from test/fixtures/reset/hooks/prepare-commit-msg.sample rename to test/fixtures/reset/git.git/hooks/prepare-commit-msg.sample diff --git a/test/fixtures/reset/hooks/update.sample b/test/fixtures/reset/git.git/hooks/update.sample similarity index 100% rename from test/fixtures/reset/hooks/update.sample rename to test/fixtures/reset/git.git/hooks/update.sample diff --git a/test/fixtures/reset/index b/test/fixtures/reset/git.git/index similarity index 100% rename from test/fixtures/reset/index rename to test/fixtures/reset/git.git/index diff --git a/test/fixtures/reset/info/exclude b/test/fixtures/reset/git.git/info/exclude similarity index 100% rename from test/fixtures/reset/info/exclude rename to test/fixtures/reset/git.git/info/exclude diff --git a/test/fixtures/reset/info/refs b/test/fixtures/reset/git.git/info/refs similarity index 100% rename from test/fixtures/reset/info/refs rename to test/fixtures/reset/git.git/info/refs diff --git a/test/fixtures/reset/logs/HEAD b/test/fixtures/reset/git.git/logs/HEAD similarity index 100% rename from test/fixtures/reset/logs/HEAD rename to test/fixtures/reset/git.git/logs/HEAD diff --git a/test/fixtures/reset/logs/refs/heads/f-gitCheckoutFiles b/test/fixtures/reset/git.git/logs/refs/heads/f-gitCheckoutFiles similarity index 100% rename from test/fixtures/reset/logs/refs/heads/f-gitCheckoutFiles rename to test/fixtures/reset/git.git/logs/refs/heads/f-gitCheckoutFiles diff --git a/test/fixtures/reset/logs/refs/heads/master b/test/fixtures/reset/git.git/logs/refs/heads/master similarity index 100% rename from test/fixtures/reset/logs/refs/heads/master rename to test/fixtures/reset/git.git/logs/refs/heads/master diff --git a/test/fixtures/reset/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 b/test/fixtures/reset/git.git/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 similarity index 100% rename from test/fixtures/reset/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 rename to test/fixtures/reset/git.git/objects/14/e5a1a3a459e05d486b98df2802ee4b30c33995 diff --git a/test/fixtures/reset/objects/41/2d321c36a34331125a77493b5dd41f5313a568 b/test/fixtures/reset/git.git/objects/41/2d321c36a34331125a77493b5dd41f5313a568 similarity index 100% rename from test/fixtures/reset/objects/41/2d321c36a34331125a77493b5dd41f5313a568 rename to test/fixtures/reset/git.git/objects/41/2d321c36a34331125a77493b5dd41f5313a568 diff --git a/test/fixtures/reset/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac b/test/fixtures/reset/git.git/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac similarity index 100% rename from test/fixtures/reset/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac rename to test/fixtures/reset/git.git/objects/55/80d8a9feeadf1c36a73a2778c62206314aebac diff --git a/test/fixtures/reset/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e b/test/fixtures/reset/git.git/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e similarity index 100% rename from test/fixtures/reset/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e rename to test/fixtures/reset/git.git/objects/56/02c1d7079f5ff3f49f341722c6d5baf93bb26e diff --git a/test/fixtures/reset/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e b/test/fixtures/reset/git.git/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e similarity index 100% rename from test/fixtures/reset/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e rename to test/fixtures/reset/git.git/objects/c2/dfadf4d76bea7fbe28086d95aa0c803237539e diff --git a/test/fixtures/reset/objects/info/packs b/test/fixtures/reset/git.git/objects/info/packs similarity index 100% rename from test/fixtures/reset/objects/info/packs rename to test/fixtures/reset/git.git/objects/info/packs diff --git a/test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx b/test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx similarity index 100% rename from test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx rename to test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.idx diff --git a/test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack b/test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack similarity index 100% rename from test/fixtures/reset/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack rename to test/fixtures/reset/git.git/objects/pack/pack-70f08ce8f755306c59b6d804345abf334b5586f8.pack diff --git a/test/fixtures/reset/packed-refs b/test/fixtures/reset/git.git/packed-refs similarity index 100% rename from test/fixtures/reset/packed-refs rename to test/fixtures/reset/git.git/packed-refs diff --git a/test/fixtures/reset/rawr.txt b/test/fixtures/reset/rawr.txt new file mode 100644 index 0000000..8baef1b --- /dev/null +++ b/test/fixtures/reset/rawr.txt @@ -0,0 +1 @@ +abc From 843be771f8bd88ddb4af8e85550952b781881b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:11:38 +0200 Subject: [PATCH 06/20] Update devDependencies, fix mocha test. --- package.json | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e65a9d8..dd3bc1b 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "main": "./lib/index", "scripts": { - "test": "mocha --compilers coffee:'./node_modules/coffee-script/lib/coffee-script/coffee-script'", + "test": "mocha --compilers coffee:'./node_modules/coffee-script/lib/coffee-script/register'", "prepublish": "coffee -o lib -c src" }, "repository": { @@ -28,11 +28,12 @@ "underscore": "1.x.x" }, "devDependencies": { - "should": "~2.0.1", - "mocha": "1.x.x", + "should": "~4.0.4", + "mocha": "~1.20.1", "sinon": "~1.7.3", - "coffee-script": "1.6.x", - "rimraf": "2.0.x" + "coffee-script": "~1.7.1", + "rimraf": "2.0.x", + "fs-extra": "^0.9.1" }, "engines": { "node": "> 0.4.1" From 91495b175dc18f968afd8730802acec4fd80fa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:11:56 +0200 Subject: [PATCH 07/20] Add tests for repo.reset --- test/repo.test.coffee | 121 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 6 deletions(-) diff --git a/test/repo.test.coffee b/test/repo.test.coffee index 98bcea2..a6635e8 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -1,7 +1,7 @@ should = require 'should' sinon = require 'sinon' -fs = require 'fs' +fs = require 'fs-extra' rimraf = require 'rimraf' fixtures = require './fixtures' git = require '../src' @@ -22,7 +22,7 @@ describe "Repo", -> git_dir = __dirname + "/fixtures/junk_add" status = null file = null - + # given a fresh new repo before (done) -> rimraf git_dir, (err) -> @@ -48,7 +48,7 @@ describe "Repo", -> repo.status (err, _status) -> status = _status done err - + it "was added", -> status.files.should.have.a.property file status.files[file].staged.should.be.true @@ -66,7 +66,7 @@ describe "Repo", -> repo.status (err, _status) -> status = _status done err - + it "was added", -> status.files.should.have.a.property file status.files[file].staged.should.be.true @@ -154,7 +154,7 @@ describe "Repo", -> return done err if err? repo.add "#{git_dir}/foo.txt", (err) -> return done err if err? - repo.commit 'message with spaces', + repo.commit 'message with spaces', author: 'Someone ' , (err) -> return done err if err? @@ -266,7 +266,7 @@ describe "Repo", -> commits[1].gpgsig.should.equal """ -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) - + iQEcBAABAgAGBQJTQw8qAAoJEL0/h9tqDFPiP3UH/RwxUS90+6DEkThcKMmV9H4K dr+D0H0z2ViMq3AHSmCydv5dWr3bupl2XyaLWWuRCxAJ78xuf98qVRIBfT/FKGeP fz+GtXkv3naCD12Ay6YiwfxSQhxFiJtRwP5rla2i7hlV3BLFPYCWTtL8OLF4CoRm @@ -487,3 +487,112 @@ describe "Repo", -> should.exist err done() + describe "#reset", -> + repo = null + git_dir = __dirname + "/fixtures/junk_reset" + status = null + file = "bla.txt" + + # given a fresh new repo + beforeEach (done) -> + status = null + rimraf git_dir, (err) -> + return done err if err + fs.copy "#{__dirname}/fixtures/reset", "#{git_dir}", (err) -> + return done err if err + fs.rename "#{git_dir}/git.git", "#{git_dir}/.git", (err) -> + return done err if err + repo = git git_dir + fs.writeFile "#{git_dir}/#{file}", "hello", (err) -> + return done err if err? + repo.add "#{git_dir}/#{file}", (err) -> + done err + + after (done) -> + rimraf git_dir, (err) -> + done err + + describe "reset without specific treeish (defaults to HEAD)", -> + describe "reset (--mixed)", -> + beforeEach (done) -> + repo.reset -> + repo.status (err, _status) -> + status = _status + done err + + it "removes the file from index, leaves it in working tree", -> + status.files.should.have.a.property file + status.files[file].staged.should.be.false + status.files[file].tracked.should.be.false + status.files[file].should.not.have.a.property 'type' + + describe "reset --soft", -> + beforeEach (done) -> + repo.reset {soft: true}, -> + repo.status (err, _status) -> + status = _status + done err + + it "leaves the added file in the index", -> + status.files.should.have.a.property file + status.files[file].staged.should.be.true + status.files[file].tracked.should.be.true + status.files[file].type.should.eql 'A' + + describe "reset --hard", -> + beforeEach (done) -> + repo.reset {hard: true}, -> + repo.status (err, _status) -> + status = _status + done err + + it "removes the file from index and working tree", -> + status.files.should.not.have.a.property file + + describe "reset to specific treeish", -> + describe "reset (--mixed) HEAD~1", -> + beforeEach (done) -> + repo.reset 'HEAD~1', -> + repo.status (err, _status) -> + status = _status + done err + + it "resets to HEAD~1, changes stay in the working tree", -> + status.files.should.have.a.property file + status.files[file].staged.should.be.false + status.files[file].tracked.should.be.false + status.files[file].should.not.have.a.property 'type' + + status.files.should.have.a.property 'rawr.txt' + status.files['rawr.txt'].staged.should.be.false + status.files['rawr.txt'].tracked.should.be.false + status.files['rawr.txt'].should.not.have.a.property 'type' + + describe "reset --soft HEAD~1", -> + beforeEach (done) -> + repo.reset 'HEAD~1', {soft: true}, -> + repo.status (err, _status) -> + status = _status + done err + + it "resets to HEAD~1, changes stay in the index and working tree", -> + status.files.should.have.a.property file + status.files[file].staged.should.be.true + status.files[file].tracked.should.be.true + status.files[file].type.should.eql 'A' + + status.files.should.have.a.property 'rawr.txt' + status.files['rawr.txt'].staged.should.be.true + status.files['rawr.txt'].tracked.should.be.true + status.files['rawr.txt'].type.should.eql 'AM' + + describe "reset --hard HEAD~1", -> + beforeEach (done) -> + repo.reset 'HEAD~1', {hard: true}, -> + repo.status (err, _status) -> + status = _status + done err + + it "resets to HEAD~1, all changes get discarded completely", -> + status.files.should.not.have.a.property file + status.files.should.not.have.a.property 'rawr.txt' From 245011f0b2a8987450cdf732c66fc7da1cf177bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:25:03 +0200 Subject: [PATCH 08/20] Fix missing () --- src/repo.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repo.coffee b/src/repo.coffee index 064a3ff..c8a6036 100644 --- a/src/repo.coffee +++ b/src/repo.coffee @@ -368,7 +368,7 @@ module.exports = class Repo options ?= {} files ?= '.' files = [files] if _.isString files - @git "checkout", options, _.flatten ['--', files], callback + @git "checkout", options, _.flatten(['--', files]), callback # Public: Commit some code. # From 84df9b382f2877fa6f1b9cc78eb3ed3fa9fe4e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:25:35 +0200 Subject: [PATCH 09/20] Add tests for repo.checkoutFile --- test/repo.test.coffee | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/test/repo.test.coffee b/test/repo.test.coffee index a6635e8..66425a2 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -596,3 +596,59 @@ describe "Repo", -> it "resets to HEAD~1, all changes get discarded completely", -> status.files.should.not.have.a.property file status.files.should.not.have.a.property 'rawr.txt' + + describe.only "#checkoutFile", -> + repo = null + git_dir = __dirname + "/fixtures/junk_checkoutFile" + status = null + file = "bla.txt" + + # given a fresh new repo + beforeEach (done) -> + status = null + rimraf git_dir, (err) -> + return done err if err + fs.copy "#{__dirname}/fixtures/reset", "#{git_dir}", (err) -> + return done err if err + fs.rename "#{git_dir}/git.git", "#{git_dir}/.git", (err) -> + return done err if err + repo = git git_dir + fs.writeFile "#{git_dir}/#{file}", "hello", (err) -> + return done err if err? + repo.add "#{git_dir}/#{file}", (err) -> + done err + + after (done) -> + rimraf git_dir, (err) -> + done err + + describe "passing no explicit files", -> + beforeEach (done) -> + repo.checkoutFile -> + repo.status (err, _status) -> + status = _status + done err + + it "discards changes in the working tree for all files", -> + status.files.should.have.a.property file + status.files[file].staged.should.be.true + status.files[file].tracked.should.be.true + status.files[file].type.should.eql 'A' + + status.files.should.have.a.property 'rawr.txt' + status.files['rawr.txt'].staged.should.be.true + status.files['rawr.txt'].tracked.should.be.true + status.files['rawr.txt'].type.should.eql 'M' + + describe "passing an explicit file", -> + beforeEach (done) -> + repo.checkoutFile 'rawr.txt', -> + repo.status (err, _status) -> + status = _status + done err + + it "discard changes to the specified file", -> + status.files.should.have.a.property 'rawr.txt' + status.files['rawr.txt'].staged.should.be.true + status.files['rawr.txt'].tracked.should.be.true + status.files['rawr.txt'].type.should.eql 'M' From 0c90e8f489056967d6082c2d7de794edd988f7d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:34:10 +0200 Subject: [PATCH 10/20] Add Repo#reset & Repo#checkoutFile to README --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 9e06532..c29f912 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,14 @@ Commit some changes. ### `Repo#checkout(treeish, callback)` `git checkout ` +### `Repo#checkoutFile([files, options, ]callback)` +Checkout some files. + + * `files` - File(s) to checkout. Pass `'.'` or nothing to checkout all files. + * `options` - + - `force` - `Boolean` + * `callback` - Receives `(err)`. + ### `Repo#sync([[remote, ]branch, ]callback)` Sync the current branch with the remote, keeping all local changes intact. @@ -194,6 +202,17 @@ The following steps are carried out: `stash`, `pull`, `push`, `stash pop`. If th * `branch` - `String` (defaults to `master`). * `callback` - Receives `(err)`. +### `Repo#reset([treeish, options, ]callback)` +Checkout files. + + * `treeish` - The git object to reset to. Defaults to HEAD. + * `options` - + - `soft` - `Boolean` + - `mixed` - `Boolean` __default__ + - `hard` - `Boolean` + - `merge` - `Boolean` + - `keep` - `Boolean` + * `callback` - Receives `(err)`. ## Commit ### `Commit#id` From 9ba1cd513df54354d7b5ae1e7241d29649e4e734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:37:16 +0200 Subject: [PATCH 11/20] :memo: --- src/repo.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repo.coffee b/src/repo.coffee index c8a6036..983a490 100644 --- a/src/repo.coffee +++ b/src/repo.coffee @@ -336,7 +336,7 @@ module.exports = class Repo # Public: Reset the git repo. # # treeish - The {String} to reset to. - # options - The {object} containing one of the following items: + # options - The {Object} containing one of the following items: # :soft - {Boolean) # :mixed - {Boolean) When no other option given git defaults to 'mixed'. # :hard - {Boolean) From 78948e255320f0a40de1382c9ef9d20a540957fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:48:36 +0200 Subject: [PATCH 12/20] :lipstick: Remove debug code --- test/repo.test.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/repo.test.coffee b/test/repo.test.coffee index 66425a2..0dd4925 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -597,7 +597,7 @@ describe "Repo", -> status.files.should.not.have.a.property file status.files.should.not.have.a.property 'rawr.txt' - describe.only "#checkoutFile", -> + describe "#checkoutFile", -> repo = null git_dir = __dirname + "/fixtures/junk_checkoutFile" status = null From 4a7aa57a6bc85536a78e4e12d16bd6e3d48182ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 21:53:13 +0200 Subject: [PATCH 13/20] Fix deprecated should calls --- test/blob.test.coffee | 8 ++++---- test/ref.test.coffee | 22 +++++++++++----------- test/repo.test.coffee | 10 +++++----- test/tag.test.coffee | 16 ++++++++-------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/blob.test.coffee b/test/blob.test.coffee index 01d5d34..cd32bd9 100644 --- a/test/blob.test.coffee +++ b/test/blob.test.coffee @@ -27,7 +27,7 @@ describe "Blob", -> it "is a string", -> data.should.be.type "string" - data.should.include "Bla" + data.should.containEql "Bla" describe "of a file in a subdir", -> repo = git "#{__dirname}/fixtures/branched" @@ -41,7 +41,7 @@ describe "Blob", -> it "is a string", -> data.should.be.type "string" - data.should.include "!!!" + data.should.containEql "!!!" describe "#dataStream", -> describe "of a file off the root", -> @@ -57,7 +57,7 @@ describe "Blob", -> it "is a string", -> data.should.be.type "string" - data.should.include "Bla" + data.should.containEql "Bla" describe "of a file in a subdir", -> repo = git "#{__dirname}/fixtures/branched" @@ -73,6 +73,6 @@ describe "Blob", -> it "is a string", -> data.should.be.type "string" - data.should.include "!!!" + data.should.containEql "!!!" diff --git a/test/ref.test.coffee b/test/ref.test.coffee index 02242a3..a56f486 100644 --- a/test/ref.test.coffee +++ b/test/ref.test.coffee @@ -15,15 +15,15 @@ describe "Ref", -> Ref.find_all repo, "remote", Ref, (err, _remotes) -> remotes = _remotes done err - + it "is an Array of Refs", -> remotes.should.be.an.instanceof Array remotes[0].should.be.an.instanceof Ref - + it "the first item is a remote", -> remotes[0].name.should.eql "origin/HEAD" remotes[0].commit.should.be.an.instanceof Commit - + it "the second item is a remote", -> remotes[1].name.should.eql "origin/master" remotes[1].commit.should.be.an.instanceof Commit @@ -37,18 +37,18 @@ describe "Head", -> Head.find_all repo, (err, h) -> heads = h done err - + it "is an Array of Heads", -> heads.should.be.an.instanceof Array heads[0].should.be.an.instanceof Head - + it "contains the branches", -> heads.should.have.lengthOf 2 names = _.map heads, ((b) -> b.name) - names.should.include "master" - names.should.include "something" - - + names.should.containEql "master" + names.should.containEql "something" + + describe ".current", -> repo = fixtures.branched branch = null @@ -56,9 +56,9 @@ describe "Head", -> Head.current repo, (err, b) -> branch = b done err - + it "is a Head", -> branch.should.be.an.instanceof Head - + it "has the correct name", -> branch.name.should.eql "master" diff --git a/test/repo.test.coffee b/test/repo.test.coffee index 0dd4925..dccef01 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -224,7 +224,7 @@ describe "Repo", -> done err it "is the latest commit on the tag", -> - commits[0].message.should.include "commit 5" + commits[0].message.should.containEql "commit 5" describe "limit the number of commits", -> repo = fixtures.tagged @@ -246,7 +246,7 @@ describe "Repo", -> done err it "returns 2 commits", -> - commits[0].message.should.include "commit 4" + commits[0].message.should.containEql "commit 4" describe "with or without gpg signature", -> repo = fixtures.gpgsigned @@ -286,8 +286,8 @@ describe "Repo", -> it "checks out branch:master", (done) -> repo.tree().blobs (err, blobs) -> blobs[0].data (err, data) -> - data.should.include "Bla" - data.should.not.include "Bla2" + data.should.containEql "Bla" + data.should.not.containEql "Bla2" done err describe "specific branch", -> @@ -297,7 +297,7 @@ describe "Repo", -> it "checks out branch:something", (done) -> repo.tree("something").blobs (err, blobs) -> blobs[0].data (err, data) -> - data.should.include "Bla2" + data.should.containEql "Bla2" done err diff --git a/test/tag.test.coffee b/test/tag.test.coffee index 98627be..4ef4aa2 100644 --- a/test/tag.test.coffee +++ b/test/tag.test.coffee @@ -11,19 +11,19 @@ describe "Tag", -> Tag.find_all repo, (err, _tags) -> tags = _tags done err - + it "is an Array of Tags", -> tags.should.be.an.instanceof Array tags[0].should.be.an.instanceof Tag - + pref = "the tag" it "#{pref} has the correct name", -> tags[0].name.should.eql "tag-1" - + it "#{pref} has the correct commit", -> tags[0].commit.id.should.eql "32bbb351de16c3e404b3b7c77601c3d124e1e1a1" - - + + describe "#message", -> repo = fixtures.tagged tags = null @@ -35,10 +35,10 @@ describe "Tag", -> tags[0].message (err, _message) -> message = _message done err - + it "is the correct message", -> - message.should.include "the first tag" - + message.should.containEql "the first tag" + it "has the correct commit", -> tags[0].commit.message.should.eql "commit 5" From 367b12b2d77222d43390b9a54b9600f458b05dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Thu, 19 Jun 2014 22:07:14 +0200 Subject: [PATCH 14/20] Escape whitespaces in pgp signature test --- test/repo.test.coffee | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/test/repo.test.coffee b/test/repo.test.coffee index dccef01..4b440f3 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -264,18 +264,17 @@ describe "Repo", -> it "contains the correct signature", -> commits[1].gpgsig.should.equal """ - -----BEGIN PGP SIGNATURE----- - Version: GnuPG v2.0.22 (GNU/Linux) - - iQEcBAABAgAGBQJTQw8qAAoJEL0/h9tqDFPiP3UH/RwxUS90+6DEkThcKMmV9H4K - dr+D0H0z2ViMq3AHSmCydv5dWr3bupl2XyaLWWuRCxAJ78xuf98qVRIBfT/FKGeP - fz+GtXkv3naCD12Ay6YiwfxSQhxFiJtRwP5rla2i7hlV3BLFPYCWTtL8OLF4CoRm - 7aF5EuDr1x7emEDyu1rf5E59ttSIySuIw0J1mTjrPCkC6lsowzTJS/vaCxZ3e7fN - iZE6VEWWY/iOxd8foJH/VZ3cfNKjfi8+Fh8t7o9ztjYTQAOZUJTn2CHB7Wkyr0Ar - HNM3v26gPFpb7UkHw0Cq2HWNV/Z7cbQc/BQ4HmrmuBPB6SWNOaBN751BbQKnPcA= - =IusH - -----END PGP SIGNATURE----- - """ + -----BEGIN#{" "}PGP#{" "}SIGNATURE----- + #{" "}Version:#{" "}GnuPG#{" "}v2.0.22#{" "}(GNU/Linux) + #{" "} + #{" "}iQEcBAABAgAGBQJTQw8qAAoJEL0/h9tqDFPiP3UH/RwxUS90+6DEkThcKMmV9H4K + #{" "}dr+D0H0z2ViMq3AHSmCydv5dWr3bupl2XyaLWWuRCxAJ78xuf98qVRIBfT/FKGeP + #{" "}fz+GtXkv3naCD12Ay6YiwfxSQhxFiJtRwP5rla2i7hlV3BLFPYCWTtL8OLF4CoRm + #{" "}7aF5EuDr1x7emEDyu1rf5E59ttSIySuIw0J1mTjrPCkC6lsowzTJS/vaCxZ3e7fN + #{" "}iZE6VEWWY/iOxd8foJH/VZ3cfNKjfi8+Fh8t7o9ztjYTQAOZUJTn2CHB7Wkyr0Ar + #{" "}HNM3v26gPFpb7UkHw0Cq2HWNV/Z7cbQc/BQ4HmrmuBPB6SWNOaBN751BbQKnPcA= + #{" "}=IusH + #{" "}-----END#{" "}PGP#{" "}SIGNATURE-----""" describe "#tree", -> repo = fixtures.branched From 365843e0718208c12f2acf1948d346826d337d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Fri, 20 Jun 2014 01:58:56 +0200 Subject: [PATCH 15/20] Reinitialize the copied git test repos --- package.json | 4 ++-- test/repo.test.coffee | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index dd3bc1b..9b750f6 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "mocha": "~1.20.1", "sinon": "~1.7.3", "coffee-script": "~1.7.1", - "rimraf": "2.0.x", - "fs-extra": "^0.9.1" + "rimraf": "2.2.x", + "fs-extra": "~0.9.1" }, "engines": { "node": "> 0.4.1" diff --git a/test/repo.test.coffee b/test/repo.test.coffee index 4b440f3..e78d81e 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -501,11 +501,12 @@ describe "Repo", -> return done err if err fs.rename "#{git_dir}/git.git", "#{git_dir}/.git", (err) -> return done err if err - repo = git git_dir - fs.writeFile "#{git_dir}/#{file}", "hello", (err) -> - return done err if err? - repo.add "#{git_dir}/#{file}", (err) -> - done err + git.init git_dir, (err) -> + repo = git git_dir + fs.writeFile "#{git_dir}/#{file}", "hello", (err) -> + return done err if err? + repo.add "#{git_dir}/#{file}", (err) -> + done err after (done) -> rimraf git_dir, (err) -> @@ -610,12 +611,13 @@ describe "Repo", -> fs.copy "#{__dirname}/fixtures/reset", "#{git_dir}", (err) -> return done err if err fs.rename "#{git_dir}/git.git", "#{git_dir}/.git", (err) -> - return done err if err - repo = git git_dir - fs.writeFile "#{git_dir}/#{file}", "hello", (err) -> - return done err if err? - repo.add "#{git_dir}/#{file}", (err) -> - done err + git.init git_dir, (err) -> + return done err if err + repo = git git_dir + fs.writeFile "#{git_dir}/#{file}", "hello", (err) -> + return done err if err? + repo.add "#{git_dir}/#{file}", (err) -> + done err after (done) -> rimraf git_dir, (err) -> From 7d300d75faaac5c65f8b78daa8cd34de963d93de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Fri, 20 Jun 2014 01:59:25 +0200 Subject: [PATCH 16/20] Disable node 0.8 on travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8852a79..6978993 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: # - "0.6" - - "0.8" +# - "0.8" - "0.10" - "0.11" From e4557ffc39498f19df9594d315bdf76f7a5d5f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Fri, 20 Jun 2014 02:08:29 +0200 Subject: [PATCH 17/20] Remove trailing whitespaces --- src/actor.coffee | 6 ++--- src/blob.coffee | 10 ++++---- src/commit.coffee | 52 ++++++++++++++++++++--------------------- src/diff.coffee | 26 ++++++++++----------- src/index.coffee | 10 ++++---- src/ref.coffee | 12 +++++----- src/status.coffee | 8 +++---- src/submodule.coffee | 32 ++++++++++++------------- src/tag.coffee | 26 ++++++++++----------- src/tree.coffee | 48 ++++++++++++++++++------------------- test/actor.test.coffee | 24 +++++++++---------- test/commit.test.coffee | 10 ++++---- test/diff.test.coffee | 30 ++++++++++++------------ test/index.test.coffee | 2 +- test/tree.test.coffee | 50 +++++++++++++++++++-------------------- 15 files changed, 173 insertions(+), 173 deletions(-) diff --git a/src/actor.coffee b/src/actor.coffee index 7f4a420..63fa71e 100644 --- a/src/actor.coffee +++ b/src/actor.coffee @@ -4,13 +4,13 @@ module.exports = class Actor constructor: (@name, @email) -> if @email @hash = crypto.createHash("md5").update(@email, "ascii").digest("hex") - + # Public: Get a string representation of the Actor. toString: -> "#{@name} <#{@email}>" - + # Public: Parse an Actor from a "bla " string. - # + # # Returns Actor. @from_string: (str) -> if /<.+>/.test str diff --git a/src/blob.coffee b/src/blob.coffee index 7965a7e..103143e 100644 --- a/src/blob.coffee +++ b/src/blob.coffee @@ -3,12 +3,12 @@ path = require 'path' module.exports = class Blob constructor: (@repo, attrs) -> {@id, @name, @mode} = attrs - + # Public: Get the blob contents. - # + # # callback - Receives `(err, data)`. - # - # Warning, this only returns files less than 200k, the standard buffer size for + # + # Warning, this only returns files less than 200k, the standard buffer size for # node's exec(). If you need to get bigger files, you should use dataStream() to # get a stream for the file's data # @@ -16,7 +16,7 @@ module.exports = class Blob @repo.git "cat-file", {p: true}, @id , (err, stdout, stderr) -> return callback err, stdout - + # Public: Get the blob contents as a stream # # returns - [dataStream, errstream] diff --git a/src/commit.coffee b/src/commit.coffee index 43902cd..c53774a 100644 --- a/src/commit.coffee +++ b/src/commit.coffee @@ -5,42 +5,42 @@ Tree = require './tree' module.exports = class Commit constructor: (@repo, @id, parents, tree, @author, @authored_date, @committer, @committed_date, @gpgsig, @message) -> # Public: Get the commit's Tree. - # + # # Returns Tree. @tree = _.memoize => (new Tree @repo, tree) - + # Public: Get the Commit's parent Commits. - # + # # Returns an Array of Commits. @parents = _.memoize => _.map parents, (parent) => new Commit @repo, parent - - + + toJSON: -> {@id, @author, @authored_date, @committer, @committed_date, @message} - - + + # Public: Find the matching commits. - # + # # callback - Receives `(err, commits)` - # + # @find_all: (repo, ref, options, callback) -> options = _.extend {pretty: "raw"}, options repo.git "rev-list", options, ref , (err, stdout, stderr) => return callback err if err return callback null, @parse_commits(repo, stdout) - - + + @find: (repo, id, callback) -> options = {pretty: "raw", "max-count": 1} repo.git "rev-list", options, id , (err, stdout, stderr) => return callback err if err return callback null, @parse_commits(repo, stdout)[0] - - + + @find_commits: (repo, ids, callback) -> commits = [] next = (i) -> @@ -53,10 +53,10 @@ module.exports = class Commit else callback null, commits next 0 - - + + # Internal: Parse the commits from `git rev-list` - # + # # Return Commit[] @parse_commits: (repo, text) -> commits = [] @@ -65,17 +65,17 @@ module.exports = class Commit id = _.last lines.shift().split(" ") break if !id tree = _.last lines.shift().split(" ") - + parents = [] while /^parent/.test lines[0] parents.push _.last lines.shift().split(" ") - + author_line = lines.shift() [author, authored_date] = @actor author_line - + committer_line = lines.shift() [committer, committed_date] = @actor committer_line - + gpgsig = [] if /^gpgsig/.test lines[0] gpgsig.push lines.shift().replace /^gpgsig /, '' @@ -86,22 +86,22 @@ module.exports = class Commit # not doing anything with this yet, but it's sometimes there if /^encoding/.test lines[0] encoding = _.last lines.shift().split(" ") - + lines.shift() - + message_lines = [] while /^ {4}/.test lines[0] message_lines.push lines.shift()[4..-1] - + while lines[0]? && !lines[0].length lines.shift() commits.push new Commit(repo, id, parents, tree, author, authored_date, committer, committed_date, gpgsig.join("\n"), message_lines.join("\n")) return commits - - + + # Internal: Parse the actor. - # + # # Returns [String name and email, Date] @actor: (line) -> [m, actor, epoch] = /^.+? (.*) (\d+) .*$/.exec line diff --git a/src/diff.coffee b/src/diff.coffee index 9c9a433..9890530 100644 --- a/src/diff.coffee +++ b/src/diff.coffee @@ -11,37 +11,37 @@ module.exports = class Diff if b_blob isnt null @b_blob = new Blob @repo, {id: b_blob} @b_sha = b_blob - + toJSON: -> {@a_path, @b_path, @a_mode, @b_mode, @new_file , @deleted_file, @diff, @renamed_file, @similarity_index} - + # Public: Parse the Diffs from the command output. - # + # # text - String stdout of a `git diff` command. - # + # # Returns Array of Diff. @parse: (repo, text) -> lines = text.split "\n" diffs = [] - + while lines.length && lines[0] # FIXME shift is O(n), so iterating n over O(n) operation might be O(n^2) [m, a_path, b_path] = ///^diff\s--git\s"?a/(.+?)"?\s"?b/(.+)"?$///.exec lines.shift() - + if /^old mode/.test lines[0] [m, a_mode] = /^old mode (\d+)/.exec lines.shift() [m, b_mode] = /^new mode (\d+)/.exec lines.shift() - + if !lines.length || /^diff --git/.test(lines[0]) diffs.push new Diff(repo, a_path, b_path, null, null, a_mode, b_mode, false, false, null) continue - + sim_index = 0 new_file = false deleted_file = false renamed_file = false - + if /^new file/.test lines[0] [m, b_mode] = /^new file mode (.+)$/.exec lines.shift() a_mode = null @@ -56,17 +56,17 @@ module.exports = class Diff # shift away the 2 `rename from/to ...` lines lines.shift() lines.shift() - + [m, a_blob, b_blob, b_mode] = ///^index\s([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+)\s?(.+)?$///.exec lines.shift() b_mode = b_mode.trim() if b_mode - + diff_lines = [] while lines[0] && !/^diff/.test(lines[0]) diff_lines.push lines.shift() diff = diff_lines.join "\n" - + diffs.push new Diff(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff, renamed_file, sim_index) - + return diffs # Public: Parse the raw diff format from the command output. diff --git a/src/index.coffee b/src/index.coffee index 927b70e..2a61bdf 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -2,18 +2,18 @@ Repo = require './repo' # Public: Create a Repo from the given path. -# +# # Returns Repo. module.exports = Git = (path, bare=false) -> return new Repo path, bare # 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, bare, callback) -> [bare, callback] = [callback, bare] if !callback if bare @@ -26,11 +26,11 @@ Git.init = (path, bare, callback) -> 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) -> diff --git a/src/ref.coffee b/src/ref.coffee index 0b66484..2aa4a2d 100644 --- a/src/ref.coffee +++ b/src/ref.coffee @@ -4,15 +4,15 @@ Commit = require './commit' exports.Ref = class Ref constructor: (@name, @commit) -> {@repo} = @commit - + # Public: Get a String representation of the Ref. toString: -> "#" - + # Internal: Find all refs. - # + # # options - (optional). - # + # # Returns Array of Ref. @find_all: (repo, type, RefClass, callback) -> repo.git.refs type, {}, (err, text) -> @@ -24,7 +24,7 @@ exports.Ref = class Ref [name, id] = ref.split(' ') names.push name ids.push id - + Commit.find_commits repo, ids, (err, commits) -> return callback err if err refs = [] @@ -36,7 +36,7 @@ exports.Ref = class Ref exports.Head = class Head extends Ref @find_all: (repo, callback) -> Ref.find_all repo, "head", Head, callback - + @current: (repo, callback) -> fs.readFile "#{repo.dot_git}/HEAD", (err, data) -> return callback err if err diff --git a/src/status.coffee b/src/status.coffee index c4f8953..fe591ed 100644 --- a/src/status.coffee +++ b/src/status.coffee @@ -1,8 +1,8 @@ # Public: Create a Status. -# +# # repo - A Repo. # callback - Receives `(err, status)` -# +# module.exports = S = (repo, callback) -> repo.git "status --porcelain", (err, stdout, stderr) -> status = new Status repo @@ -11,13 +11,13 @@ module.exports = S = (repo, callback) -> S.Status = class Status constructor: (@repo) -> - + # Internal: Parse the status from stdout of a `git status` command. parse: (text) -> @files = {} @clean = text.length == 0 for line in text.split("\n") - if line.length == 0 + if line.length == 0 continue file = line.substr 3 type = line.substr 0,2 diff --git a/src/submodule.coffee b/src/submodule.coffee index bc4cef7..2a13640 100644 --- a/src/submodule.coffee +++ b/src/submodule.coffee @@ -1,59 +1,59 @@ module.exports = class Submodule constructor: (@repo, options) -> {@id, @name, @mode} = options - + # Public: Get the URL of the submodule. - # + # # treeish - String treeish to look up the url within. # callback - Receives `(err, url)`. - # + # url: (treeish, callback) -> [treeish, callback] = [callback, treeish] if !callback treeish ?= "master" - + Submodule.config @repo, treeish, (err, config) => return callback err, config?[@name].url - - + + # Internal: Parse the `.gitmodules` file. - # + # # repo - A Repo. # treeish - String # callback - Receives `(err, config)`, where the config object has # the submodule names as its keys. - # + # # Examples - # + # # The following `.gitmodules` file: - # + # # [submodule "spoon-knife"] # path = spoon-knife # url = git://github.com/octocat/Spoon-Knife.git - # + # # would parse to: - # + # # { "spoon-knife": # { "path": "spoon-knife" # , "url": "git://github.com/octocat/Spoon-Knife.git" # } # } - # + # @config: (repo, treeish, callback) -> repo.tree(treeish).find ".gitmodules", (err, blob) -> return callback err if err blob.data (err, data) -> return callback err if err - + conf = {} lines = data.split "\n" current = null while lines.length line = lines.shift() - + if match = /^\[submodule "(.+)"\]$/.exec line current = match[1] conf[current] = {} else if match = /^\s+([^\s]+)\s+[=]\s+(.+)$/.exec line conf[current][match[1]] = match[2] - + return callback null, conf diff --git a/src/tag.coffee b/src/tag.coffee index 937259a..b57b81a 100644 --- a/src/tag.coffee +++ b/src/tag.coffee @@ -6,32 +6,32 @@ Actor = require './actor' module.exports = class Tag extends Ref @find_all: (repo, callback) -> Ref.find_all repo, "tag", Tag, callback - - + + # Public: Get the tag message. - # + # # Returns String. message: (callback) -> @lazy (err, data) -> return callback err if err return callback null, data.message - + # Public: Get the tag author. - # + # # Returns Actor. tagger: (callback) -> @lazy (err, data) -> return callback err if err return callback null, data.tagger - + # Public: Get the date that the tag was created. - # + # # Returns Date. tag_date: (callback) -> @lazy (err, data) -> return callback err if err return callback null, data.tag_date - + # Internal: Load the tag data. lazy: (callback) -> return callback null, @_lazy_data if @_lazy_data @@ -40,23 +40,23 @@ module.exports = class Tag extends Ref return callback err if err lines = stdout.split "\n" data = {} - + lines.shift() # object 4ae1cc5e6c7bb85b14ecdf221030c71d0654a42e lines.shift() # type commit lines.shift() # tag v0.0.2 - + # bob author_line = lines.shift() [m, author, epoch] = /^.+? (.*) (\d+) .*$/.exec author_line - + data.tagger = Actor.from_string author data.tag_date = new Date epoch - + lines.shift() message = [] while line = lines.shift() message.push line data.message = message.join("\n") - + return callback null, (@_lazy_data = data) diff --git a/src/tree.coffee b/src/tree.coffee index c0c5d5f..3d67221 100644 --- a/src/tree.coffee +++ b/src/tree.coffee @@ -11,13 +11,13 @@ module.exports = class Tree @id = options else {@id, @name, @mode} = options - - + + # Public: Get the children of the tree. - # + # # callback - Receives `(err, children)`, where children is a list # of Trees, Blobs, and Submodules. - # + # contents: (callback) -> return callback null, @_contents if @_contents @repo.git "ls-tree", {}, @id @@ -27,35 +27,35 @@ module.exports = class Tree for line in stdout.split("\n") @_contents.push @content_from_string(line) if line return callback null, @_contents - - + + # Public: Get the child blobs. - # + # # callback - Receives `(err, blobs)`. - # + # blobs: (callback) -> @contents (err, children) -> return callback err if err return callback null, _.filter children, (child) -> child instanceof Blob - - + + # Public: Get the child blobs. - # + # # callback - Receives `(err, trees)`. - # + # trees: (callback) -> @contents (err, children) -> return callback err if err return callback null, _.filter children, (child) -> child instanceof Tree - - + + # Public: Find the named object in this tree's contents. - # + # # callback - Receives `(err, obj)` where obj is Tree, Blob, or null # if not found. - # + # find: (file, callback) -> if /\//.test file [dir, rest] = file.split "/", 2 @@ -70,17 +70,17 @@ module.exports = class Tree if child.name == file return callback null, child return callback null, null - - + + # Internal: Parse a Blob or Tree from the line. - # + # # line - String - # + # # Examples - # + # # tree.content_from_string "100644 blob e4ff69dd8f19d770e9731b4bc424ccb695f0b5ad README.md" # # => # - # + # # Returns Blob, Tree or Submodule. content_from_string: (line) -> [mode, type, id, name] = line.split /[\t ]+/, 4 @@ -95,9 +95,9 @@ module.exports = class Tree new Submodule @repo, {id, name, mode} else throw new Error "Invalid object type: '#{type}'" - + # Public: Get a String representation of the Tree. - # + # # Returns String. toString: -> "#" diff --git a/test/actor.test.coffee b/test/actor.test.coffee index dbaab48..2e5be34 100644 --- a/test/actor.test.coffee +++ b/test/actor.test.coffee @@ -6,38 +6,38 @@ describe "Actor", -> actor = new Actor "bob", "bob@example.com" it "assigns @name", -> actor.name.should.eql "bob" - + it "assigns @email", -> actor.email.should.eql "bob@example.com" - - + + describe "#toString", -> actor = new Actor "bob", "bob@example.com" - + it "is a string representation of the actor", -> actor.toString().should.eql "bob " - - + + describe "#hash", -> actor = new Actor "bob", "bob@example.com" - + it "is the md5 hash of the email", -> actor.hash.should.eql "4b9bb80620f03eb3719e0a061c14283d" - - + + describe ".from_string", -> describe "with a name and email", -> actor = Actor.from_string "bob " it "parses the name", -> actor.name.should.eql "bob" - + it "parses the email", -> actor.email.should.eql "bob@example.com" - + describe "with only a name", -> actor = Actor.from_string "bob" it "parses the name", -> actor.name.should.eql "bob" - + it "does not parse the email", -> should.not.exist actor.email diff --git a/test/commit.test.coffee b/test/commit.test.coffee index 8ae427b..9b5630a 100644 --- a/test/commit.test.coffee +++ b/test/commit.test.coffee @@ -12,11 +12,11 @@ describe "Commit", -> repo.commits "master", (err, commits) -> tree = commits[0].tree() done err - + it "passes a tree", -> tree.should.be.an.instanceof Tree - - + + describe "#parents", -> repo = fixtures.branched parents = null @@ -26,10 +26,10 @@ describe "Commit", -> parents = commits[0].parents() parent = commits[1] done err - + it "is an Array of Commits", -> parents.should.be.an.instanceof Array parents[0].should.be.an.instanceof Commit - + it "has the parent commit", -> parents[0].id.should.eql parent.id diff --git a/test/diff.test.coffee b/test/diff.test.coffee index 8cbf1fa..eccb9a4 100644 --- a/test/diff.test.coffee +++ b/test/diff.test.coffee @@ -19,38 +19,38 @@ describe "Diff", -> +12 """ diffs = Diff.parse repo, stdout - + it "is an Array of Diffs", -> diffs.should.be.an.instanceof Array diffs[0].should.be.an.instanceof Diff - + it "has one diff", -> diffs.should.have.lengthOf 1 - + describe "the first diff", -> diff = diffs[0] - + it "has the repo", -> diff.repo.should.eql repo - + for blob in ["a_blob", "b_blob"] it "has a #{blob}", -> diff[blob].should.be.an.instanceof Blob - + for path in ["a_path", "b_path"] it "has a #{path}", -> diff[path].should.eql "file.txt" - + it "has a b_mode", -> diff.b_mode.should.eql "100644" - + for change in ["new_file", "renamed_file", "deleted_file"] it "#{change} is false", -> diff[change].should.be.false - + it "has a similarity_index of 0", -> diff.similarity_index.should.eql 0 - + describe ".parse_raw", -> describe "simple editing", -> repo = fixtures.tagged @@ -109,15 +109,15 @@ describe "Diff", -> -!!! """ diffs = Diff.parse repo, stdout - + it "has 2 diffs", -> diffs.should.have.lengthOf 2 - + describe "the second diff", -> diff = diffs[1] it "deletes a file", -> diff.deleted_file.should.be.true - + describe "create a file", -> repo = fixtures.branched stdout = """ @@ -130,8 +130,8 @@ describe "Diff", -> +!!! """ diffs = Diff.parse repo, stdout - + it "creates a file", -> diffs[0].new_file.should.be.true - + diff --git a/test/index.test.coffee b/test/index.test.coffee index 9f47ed1..af59585 100644 --- a/test/index.test.coffee +++ b/test/index.test.coffee @@ -18,7 +18,7 @@ describe "git", -> git.init newRepositoryDir, (err, _repo) -> repo = _repo done err - it "inits a Repo", -> + it "inits a Repo", -> repo.should.be.an.instanceof Repo bare = repo.bare || false bare.should.be.false diff --git a/test/tree.test.coffee b/test/tree.test.coffee index f10555b..153ed25 100644 --- a/test/tree.test.coffee +++ b/test/tree.test.coffee @@ -11,77 +11,77 @@ describe "Tree", -> repo = fixtures.branched tree = repo.tree() contents = null - + before (done) -> tree.contents (err, _contents) -> contents = _contents done err - + it "is an Array", -> contents.should.be.an.instanceof Array - + it "contains a Blob", -> contents[0].should.be.an.instanceof Blob contents[0].name.should.eql "README.md" - + it "contains a Tree", -> contents[1].should.be.an.instanceof Tree contents[1].name.should.eql "some" - + describe "with submodules", -> repo = fixtures.submodule tree = repo.tree() contents = null - + before (done) -> tree.contents (err, _contents) -> contents = _contents done err - + it "contains a Submodule", (done) -> contents[2].should.be.an.instanceof Submodule contents[2].name.should.eql "spoon-knife" contents[2].url (err, url) -> url.should.eql "git://github.com/octocat/Spoon-Knife.git" done err - - + + describe "#blobs", -> repo = fixtures.branched tree = repo.tree() blobs = null - + before (done) -> tree.blobs (err, _blobs) -> blobs = _blobs done err - + it "has only 1 item", -> blobs.should.have.lengthOf 1 - + it "contains a Blob", -> blobs[0].should.be.an.instanceof Blob blobs[0].name.should.eql "README.md" - - + + describe "#trees", -> repo = fixtures.branched tree = repo.tree() trees = null - + before (done) -> tree.trees (err, _trees) -> trees = _trees done err - + it "has only 1 item", -> trees.should.have.lengthOf 1 - + it "contains a Tree", -> trees[0].should.be.an.instanceof Tree trees[0].name.should.eql "some" - - + + describe "#find", -> repo = fixtures.branched tree = repo.tree() @@ -91,29 +91,29 @@ describe "Tree", -> tree.find "README.md", (err, _blob) -> blob = _blob done err - + it "finds the Blob", -> blob.should.be.an.instanceof Blob blob.name.should.eql "README.md" - + describe "find a directory", -> subtree = null before (done) -> tree.find "some", (err, _tree) -> subtree = _tree done err - + it "finds the Tree", -> subtree.should.be.an.instanceof Tree subtree.name.should.eql "some" - + describe "find inside a directory", -> blob = null before (done) -> tree.find "some/hi.txt", (err, _blob) -> blob = _blob done err - + it "finds the Blob", -> blob.should.be.an.instanceof Blob blob.name.should.eql "hi.txt" @@ -124,7 +124,7 @@ describe "Tree", -> tree.find "nonexistant", (err, _tree) -> subtree = _tree done err - + it "is null", -> should.not.exist subtree From 3208203f37d70fc1a74ae94af2132de1bf81937b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Fri, 20 Jun 2014 13:24:40 +0200 Subject: [PATCH 18/20] Force updating npm to avoid travis errors --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6978993..14607b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ language: node_js node_js: # - "0.6" -# - "0.8" + - "0.8" - "0.10" - "0.11" + +install: + - "npm install -g npm" + - "npm install" From f9f3ce43bef04b6813de479dbbe2735db983e301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Fri, 20 Jun 2014 13:39:23 +0200 Subject: [PATCH 19/20] Replace rimraf with fs-extra --- package.json | 1 - test/repo.test.coffee | 21 ++++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 9b750f6..b9fe6f4 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "mocha": "~1.20.1", "sinon": "~1.7.3", "coffee-script": "~1.7.1", - "rimraf": "2.2.x", "fs-extra": "~0.9.1" }, "engines": { diff --git a/test/repo.test.coffee b/test/repo.test.coffee index e78d81e..c97cf2c 100644 --- a/test/repo.test.coffee +++ b/test/repo.test.coffee @@ -2,7 +2,6 @@ should = require 'should' sinon = require 'sinon' fs = require 'fs-extra' -rimraf = require 'rimraf' fixtures = require './fixtures' git = require '../src' Actor = require '../src/actor' @@ -25,7 +24,7 @@ describe "Repo", -> # given a fresh new repo before (done) -> - rimraf git_dir, (err) -> + fs.remove git_dir, (err) -> return done err if err fs.mkdir git_dir, '0755', (err) -> return done err if err @@ -35,7 +34,7 @@ describe "Repo", -> done() after (done) -> - rimraf git_dir, done + fs.remove git_dir, done describe "with only a file", -> file = 'foo.txt' @@ -142,7 +141,7 @@ describe "Repo", -> # given a fresh new repo before (done) -> - rimraf git_dir, (err) -> + fs.remove git_dir, (err) -> return done err if err? fs.mkdir git_dir, '0755', (err) -> return done err if err? @@ -163,7 +162,7 @@ describe "Repo", -> done err after (done) -> - rimraf git_dir, done + fs.remove git_dir, done it "has right message", (done) -> commit.message.should.eql 'message with spaces' @@ -398,7 +397,7 @@ describe "Repo", -> git_dir = __dirname + "/fixtures/junk_create_tag" before (done) -> - rimraf git_dir, (err) -> + fs.remove git_dir, (err) -> return done err if err fs.mkdir git_dir, 0o755, (err) -> return done err if err @@ -412,7 +411,7 @@ describe "Repo", -> repo.commit "initial commit", {all: true}, done after (done) -> - rimraf git_dir, done + fs.remove git_dir, done it "creates a tag", (done) -> repo.create_tag "foo", done @@ -495,7 +494,7 @@ describe "Repo", -> # given a fresh new repo beforeEach (done) -> status = null - rimraf git_dir, (err) -> + fs.remove git_dir, (err) -> return done err if err fs.copy "#{__dirname}/fixtures/reset", "#{git_dir}", (err) -> return done err if err @@ -509,7 +508,7 @@ describe "Repo", -> done err after (done) -> - rimraf git_dir, (err) -> + fs.remove git_dir, (err) -> done err describe "reset without specific treeish (defaults to HEAD)", -> @@ -606,7 +605,7 @@ describe "Repo", -> # given a fresh new repo beforeEach (done) -> status = null - rimraf git_dir, (err) -> + fs.remove git_dir, (err) -> return done err if err fs.copy "#{__dirname}/fixtures/reset", "#{git_dir}", (err) -> return done err if err @@ -620,7 +619,7 @@ describe "Repo", -> done err after (done) -> - rimraf git_dir, (err) -> + fs.remove git_dir, (err) -> done err describe "passing no explicit files", -> From e1a8fc6e956ef008b184a1d6d336216c258bfa37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Sch=C3=BC=C3=9Fler?= Date: Sun, 6 Jul 2014 22:20:01 +0200 Subject: [PATCH 20/20] Cleanup reset fixture --- test/fixtures/reset/git.git/COMMIT_EDITMSG | 1 - test/fixtures/reset/git.git/ORIG_HEAD | 1 - test/fixtures/reset/git.git/description | 1 - .../reset/git.git/hooks/applypatch-msg.sample | 15 -- .../reset/git.git/hooks/commit-msg.sample | 24 --- .../reset/git.git/hooks/post-update.sample | 8 - .../reset/git.git/hooks/pre-applypatch.sample | 14 -- .../reset/git.git/hooks/pre-commit.sample | 49 ----- .../reset/git.git/hooks/pre-push.sample | 54 ------ .../reset/git.git/hooks/pre-rebase.sample | 169 ------------------ .../git.git/hooks/prepare-commit-msg.sample | 36 ---- .../reset/git.git/hooks/update.sample | 128 ------------- test/fixtures/reset/git.git/index | Bin 334 -> 334 bytes test/fixtures/reset/git.git/info/exclude | 6 - test/fixtures/reset/git.git/info/refs | 2 - test/fixtures/reset/git.git/logs/HEAD | 12 -- .../logs/refs/heads/f-gitCheckoutFiles | 2 - .../reset/git.git/logs/refs/heads/master | 4 - test/fixtures/reset/git.git/packed-refs | 3 - .../git.git/refs/heads/f-gitCheckoutFiles | 1 + test/fixtures/reset/git.git/refs/heads/master | 1 + 21 files changed, 2 insertions(+), 529 deletions(-) delete mode 100644 test/fixtures/reset/git.git/COMMIT_EDITMSG delete mode 100644 test/fixtures/reset/git.git/ORIG_HEAD delete mode 100644 test/fixtures/reset/git.git/description delete mode 100755 test/fixtures/reset/git.git/hooks/applypatch-msg.sample delete mode 100755 test/fixtures/reset/git.git/hooks/commit-msg.sample delete mode 100755 test/fixtures/reset/git.git/hooks/post-update.sample delete mode 100755 test/fixtures/reset/git.git/hooks/pre-applypatch.sample delete mode 100755 test/fixtures/reset/git.git/hooks/pre-commit.sample delete mode 100755 test/fixtures/reset/git.git/hooks/pre-push.sample delete mode 100755 test/fixtures/reset/git.git/hooks/pre-rebase.sample delete mode 100755 test/fixtures/reset/git.git/hooks/prepare-commit-msg.sample delete mode 100755 test/fixtures/reset/git.git/hooks/update.sample delete mode 100644 test/fixtures/reset/git.git/info/exclude delete mode 100644 test/fixtures/reset/git.git/info/refs delete mode 100644 test/fixtures/reset/git.git/logs/HEAD delete mode 100644 test/fixtures/reset/git.git/logs/refs/heads/f-gitCheckoutFiles delete mode 100644 test/fixtures/reset/git.git/logs/refs/heads/master delete mode 100644 test/fixtures/reset/git.git/packed-refs create mode 100644 test/fixtures/reset/git.git/refs/heads/f-gitCheckoutFiles create mode 100644 test/fixtures/reset/git.git/refs/heads/master diff --git a/test/fixtures/reset/git.git/COMMIT_EDITMSG b/test/fixtures/reset/git.git/COMMIT_EDITMSG deleted file mode 100644 index 406ba8c..0000000 --- a/test/fixtures/reset/git.git/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -Second commit. diff --git a/test/fixtures/reset/git.git/ORIG_HEAD b/test/fixtures/reset/git.git/ORIG_HEAD deleted file mode 100644 index e2759dd..0000000 --- a/test/fixtures/reset/git.git/ORIG_HEAD +++ /dev/null @@ -1 +0,0 @@ -2bef842346e4511c21c592fda70dd45b1dcac863 diff --git a/test/fixtures/reset/git.git/description b/test/fixtures/reset/git.git/description deleted file mode 100644 index 498b267..0000000 --- a/test/fixtures/reset/git.git/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/test/fixtures/reset/git.git/hooks/applypatch-msg.sample b/test/fixtures/reset/git.git/hooks/applypatch-msg.sample deleted file mode 100755 index 8b2a2fe..0000000 --- a/test/fixtures/reset/git.git/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -test -x "$GIT_DIR/hooks/commit-msg" && - exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} -: diff --git a/test/fixtures/reset/git.git/hooks/commit-msg.sample b/test/fixtures/reset/git.git/hooks/commit-msg.sample deleted file mode 100755 index b58d118..0000000 --- a/test/fixtures/reset/git.git/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/test/fixtures/reset/git.git/hooks/post-update.sample b/test/fixtures/reset/git.git/hooks/post-update.sample deleted file mode 100755 index ec17ec1..0000000 --- a/test/fixtures/reset/git.git/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/test/fixtures/reset/git.git/hooks/pre-applypatch.sample b/test/fixtures/reset/git.git/hooks/pre-applypatch.sample deleted file mode 100755 index b1f187c..0000000 --- a/test/fixtures/reset/git.git/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -test -x "$GIT_DIR/hooks/pre-commit" && - exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} -: diff --git a/test/fixtures/reset/git.git/hooks/pre-commit.sample b/test/fixtures/reset/git.git/hooks/pre-commit.sample deleted file mode 100755 index 68d62d5..0000000 --- a/test/fixtures/reset/git.git/hooks/pre-commit.sample +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ASCII filenames set this variable to true. -allownonascii=$(git config --bool hooks.allownonascii) - -# Redirect output to stderr. -exec 1>&2 - -# Cross platform projects tend to avoid non-ASCII filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test $(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 -then - cat <<\EOF -Error: Attempt to add a non-ASCII file name. - -This can cause problems if you want to work with people on other platforms. - -To be portable it is advisable to rename the file. - -If you know what you are doing you can disable this check using: - - git config hooks.allownonascii true -EOF - exit 1 -fi - -# If there are whitespace errors, print the offending file names and fail. -exec git diff-index --check --cached $against -- diff --git a/test/fixtures/reset/git.git/hooks/pre-push.sample b/test/fixtures/reset/git.git/hooks/pre-push.sample deleted file mode 100755 index 1f3bceb..0000000 --- a/test/fixtures/reset/git.git/hooks/pre-push.sample +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh - -# An example hook script to verify what is about to be pushed. Called by "git -# push" after it has checked the remote status, but before anything has been -# pushed. If this script exits with a non-zero status nothing will be pushed. -# -# This hook is called with the following parameters: -# -# $1 -- Name of the remote to which the push is being done -# $2 -- URL to which the push is being done -# -# If pushing without using a named remote those arguments will be equal. -# -# Information about the commits which are being pushed is supplied as lines to -# the standard input in the form: -# -# -# -# This sample shows how to prevent push of commits where the log message starts -# with "WIP" (work in progress). - -remote="$1" -url="$2" - -z40=0000000000000000000000000000000000000000 - -IFS=' ' -while read local_ref local_sha remote_ref remote_sha -do - if [ "$local_sha" = $z40 ] - then - # Handle delete - : - else - if [ "$remote_sha" = $z40 ] - then - # New branch, examine all commits - range="$local_sha" - else - # Update to existing branch, examine new commits - range="$remote_sha..$local_sha" - fi - - # Check for WIP commit - commit=`git rev-list -n 1 --grep '^WIP' "$range"` - if [ -n "$commit" ] - then - echo "Found WIP commit in $local_ref, not pushing" - exit 1 - fi - fi -done - -exit 0 diff --git a/test/fixtures/reset/git.git/hooks/pre-rebase.sample b/test/fixtures/reset/git.git/hooks/pre-rebase.sample deleted file mode 100755 index 33730ca..0000000 --- a/test/fixtures/reset/git.git/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up-to-date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -<<\DOC_END - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". - -DOC_END diff --git a/test/fixtures/reset/git.git/hooks/prepare-commit-msg.sample b/test/fixtures/reset/git.git/hooks/prepare-commit-msg.sample deleted file mode 100755 index f093a02..0000000 --- a/test/fixtures/reset/git.git/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first comments out the -# "Conflicts:" part of a merge commit. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -case "$2,$3" in - merge,) - /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; - -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$1" ;; - - *) ;; -esac - -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/test/fixtures/reset/git.git/hooks/update.sample b/test/fixtures/reset/git.git/hooks/update.sample deleted file mode 100755 index d847583..0000000 --- a/test/fixtures/reset/git.git/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to blocks unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/test/fixtures/reset/git.git/index b/test/fixtures/reset/git.git/index index 54b94a986956a960d700fec1a52909e4bedd94b6..936ee3b3d27dc1141763f15679e406061eb4499e 100644 GIT binary patch delta 119 zcmX@dbdE{I#WTp6fq{Vuh*^Snu05x?O;SI2=Nexw>9qksF$soy5;hZ648^fa*-p&C gC1p2pOPk228xM46nQB$M%n~(d{8oS3MN^;v0F(77J^%m! delta 119 zcmX@dbdE{I#WTp6fq{Vuh*^Rc^E}`?CI+X0Vv-DJSf))>F%-ut#mYA^2Zt2Pw~1TY bL{{#9b7D>0H$Ih!b`^_9=Z>xF+V%nfx27j= diff --git a/test/fixtures/reset/git.git/info/exclude b/test/fixtures/reset/git.git/info/exclude deleted file mode 100644 index a5196d1..0000000 --- a/test/fixtures/reset/git.git/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/test/fixtures/reset/git.git/info/refs b/test/fixtures/reset/git.git/info/refs deleted file mode 100644 index 6f80955..0000000 --- a/test/fixtures/reset/git.git/info/refs +++ /dev/null @@ -1,2 +0,0 @@ -40216d142a8bf81e327f510990f2357dfd404486 refs/heads/f-gitCheckoutFiles -bdc76865cfc1d089ee4e238035a5860357c36506 refs/heads/master diff --git a/test/fixtures/reset/git.git/logs/HEAD b/test/fixtures/reset/git.git/logs/HEAD deleted file mode 100644 index bd84dd9..0000000 --- a/test/fixtures/reset/git.git/logs/HEAD +++ /dev/null @@ -1,12 +0,0 @@ -0000000000000000000000000000000000000000 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1402436637 +0200 commit (initial): Initial commit -b54f2aa124bb81b547fa5b2cf57caf23076d85ff b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192551 +0200 checkout: moving from master to master -b54f2aa124bb81b547fa5b2cf57caf23076d85ff b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192582 +0200 checkout: moving from master to f-gitCheckoutFiles -b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192722 +0200 commit: lol -40216d142a8bf81e327f510990f2357dfd404486 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192725 +0200 checkout: moving from f-gitCheckoutFiles to master -b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192736 +0200 checkout: moving from master to f-gitCheckoutFiles -40216d142a8bf81e327f510990f2357dfd404486 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192748 +0200 checkout: moving from f-gitCheckoutFiles to master -b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192813 +0200 checkout: moving from master to f-gitCheckoutFiles -40216d142a8bf81e327f510990f2357dfd404486 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192822 +0200 checkout: moving from f-gitCheckoutFiles to master -b54f2aa124bb81b547fa5b2cf57caf23076d85ff 2bef842346e4511c21c592fda70dd45b1dcac863 Maximilian Schüßler 1403194884 +0200 commit: LOL -2bef842346e4511c21c592fda70dd45b1dcac863 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403198029 +0200 reset: moving to HEAD~1 -b54f2aa124bb81b547fa5b2cf57caf23076d85ff bdc76865cfc1d089ee4e238035a5860357c36506 Maximilian Schüßler 1403198059 +0200 commit: Second commit. diff --git a/test/fixtures/reset/git.git/logs/refs/heads/f-gitCheckoutFiles b/test/fixtures/reset/git.git/logs/refs/heads/f-gitCheckoutFiles deleted file mode 100644 index 922497b..0000000 --- a/test/fixtures/reset/git.git/logs/refs/heads/f-gitCheckoutFiles +++ /dev/null @@ -1,2 +0,0 @@ -0000000000000000000000000000000000000000 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403192582 +0200 branch: Created from HEAD -b54f2aa124bb81b547fa5b2cf57caf23076d85ff 40216d142a8bf81e327f510990f2357dfd404486 Maximilian Schüßler 1403192722 +0200 commit: lol diff --git a/test/fixtures/reset/git.git/logs/refs/heads/master b/test/fixtures/reset/git.git/logs/refs/heads/master deleted file mode 100644 index a8c5951..0000000 --- a/test/fixtures/reset/git.git/logs/refs/heads/master +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1402436637 +0200 commit (initial): Initial commit -b54f2aa124bb81b547fa5b2cf57caf23076d85ff 2bef842346e4511c21c592fda70dd45b1dcac863 Maximilian Schüßler 1403194884 +0200 commit: LOL -2bef842346e4511c21c592fda70dd45b1dcac863 b54f2aa124bb81b547fa5b2cf57caf23076d85ff Maximilian Schüßler 1403198029 +0200 reset: moving to HEAD~1 -b54f2aa124bb81b547fa5b2cf57caf23076d85ff bdc76865cfc1d089ee4e238035a5860357c36506 Maximilian Schüßler 1403198059 +0200 commit: Second commit. diff --git a/test/fixtures/reset/git.git/packed-refs b/test/fixtures/reset/git.git/packed-refs deleted file mode 100644 index f4fa139..0000000 --- a/test/fixtures/reset/git.git/packed-refs +++ /dev/null @@ -1,3 +0,0 @@ -# pack-refs with: peeled fully-peeled -40216d142a8bf81e327f510990f2357dfd404486 refs/heads/f-gitCheckoutFiles -bdc76865cfc1d089ee4e238035a5860357c36506 refs/heads/master diff --git a/test/fixtures/reset/git.git/refs/heads/f-gitCheckoutFiles b/test/fixtures/reset/git.git/refs/heads/f-gitCheckoutFiles new file mode 100644 index 0000000..13e89e5 --- /dev/null +++ b/test/fixtures/reset/git.git/refs/heads/f-gitCheckoutFiles @@ -0,0 +1 @@ +40216d142a8bf81e327f510990f2357dfd404486 diff --git a/test/fixtures/reset/git.git/refs/heads/master b/test/fixtures/reset/git.git/refs/heads/master new file mode 100644 index 0000000..e12521a --- /dev/null +++ b/test/fixtures/reset/git.git/refs/heads/master @@ -0,0 +1 @@ +bdc76865cfc1d089ee4e238035a5860357c36506