diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8566567 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "shFlags"] + path = shFlags + url = git://github.com/nvie/shFlags.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a828d7e --- /dev/null +++ b/Makefile @@ -0,0 +1,59 @@ +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +# Determine if we're inside a debian build .. +ifdef DEB_BUILD_ARCH + prefix=$(DESTDIR)/usr/ +else + prefix=/usr/local +endif + +# files that need mode 755 +EXEC_FILES=git-now + +# files that need mode 644 +SCRIPT_FILES =git-now-add +SCRIPT_FILES+=git-now-grep +SCRIPT_FILES+=git-now-rebase +SCRIPT_FILES+=gitnow-common +SCRIPT_FILES+=gitnow-shFlags + +all: + @echo "usage: make install" + @echo " make uninstall" + +install: + install -d -m 0755 $(prefix)/bin + install -m 0755 $(EXEC_FILES) $(prefix)/bin + install -m 0644 $(SCRIPT_FILES) $(prefix)/bin + +uninstall: + test -d $(prefix)/bin && \ + cd $(prefix)/bin && \ + rm -f $(EXEC_FILES) $(SCRIPT_FILES) diff --git a/.vimrc b/etc/.vimrc similarity index 100% rename from .vimrc rename to etc/.vimrc diff --git a/git-now.el b/etc/git-now.el similarity index 100% rename from git-now.el rename to etc/git-now.el diff --git a/git-now b/git-now index bc1caf9..9ee7500 100755 --- a/git-now +++ b/git-now @@ -1,20 +1,75 @@ #!/bin/sh -PREFIX="from now" -MESSAGE="[${PREFIX}] `date +\"%Y/%m/%d %T\"`" - -if [ $# -eq 0 ] -then - git add -u - printf "${MESSAGE}\n\n%s" "`git diff --cached`" | git commit -F - -else -then - if [ $1 != "--all" ] - then - git add $@ - else - git add -u - git add . - fi - printf "${MESSAGE}\n\n%s" "`git diff --cached`" | git commit -F - +# enable debug mode +if [ "$DEBUG" = "yes" ]; then + set -x fi + +export GITNOW_DIR=$(dirname "$0") +PREFIX="from now" + +usage() { + echo "usage: git now [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]" + echo " [--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N]" + echo " [--refresh] [--ignore-errors] [--ignore-missing] [--]" + echo " [...]" + echo + echo " git now " + echo + echo "Available subcommands are:" + echo " add default subcommand." + echo " rebase rebase for temporary commits." + echo " grep grep temporary commits." + echo + echo "Try 'git now help' for details." +} + +main() { + # load common functionality + . "$GITNOW_DIR/gitnow-common" + + # This environmental variable fixes non-POSIX getopt style argument + # parsing, effectively breaking git-now subcommand parsing on several + # Linux platforms. + export POSIXLY_CORRECT=1 + + # use the shFlags project to parse the command line arguments + . "$GITNOW_DIR/gitnow-shFlags" + + SUBCOMMAND="$1" + if [ ! -e "$GITNOW_DIR/git-now-$SUBCOMMAND" ]; then + if [ "$SUBCOMMAND" = "help" ]; then + usage + exit 0 + else + SUBCOMMAND="add" + fi + else + FLAGS_PARENT="git now" + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}"; shift + + FLAGS_PARENT="git now $SUBCOMMAND" + fi + + # run command + . "$GITNOW_DIR/git-now-$SUBCOMMAND" + + # test if the first argument is a flag (i.e. starts with '-') + # in that case, we interpret this arg as a flag for the default + # command + SUBACTION="default" + if [ "$1" = "help" ] && { ! echo "$1" | grep -q "^-"; } then + SUBACTION="$1"; shift + fi + #if ! type "cmd_$SUBACTION" >/dev/null 2>&1; then + #warn "Unknown subcommand: '$SUBACTION'" + #usage + #exit 1 + #fi + + # run the specified action + cmd_$SUBACTION "$@" +} + +main "$@" diff --git a/git-now-add b/git-now-add new file mode 100644 index 0000000..0976d63 --- /dev/null +++ b/git-now-add @@ -0,0 +1,28 @@ +usage() { + echo "usage: git now add [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]" + echo " [--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N]" + echo " [--refresh] [--ignore-errors] [--ignore-missing] [--]" + echo " [...]" +} + +cmd_default() { + MESSAGE="[${PREFIX}] `date +\"%Y/%m/%d %T\"`" + if [ $# -eq 0 ]; then + git add -u + printf "${MESSAGE}\n\n%s" "`git diff --cached`" | git commit -F - + else + if [ $1 != "--all" ]; then + git add $@ + else + git add -u + git add . + fi + printf "${MESSAGE}\n\n%s" "`git diff --cached`" | git commit -F - + fi +} + +cmd_help() { + usage + exit 0 +} + diff --git a/git-now-grep b/git-now-grep new file mode 100644 index 0000000..d1d6e56 --- /dev/null +++ b/git-now-grep @@ -0,0 +1,29 @@ +usage() { + echo "usage: git now grep []" +} + +cmd_default() { + parse_args "$@" + + if [ -n "$BASE_BRANCH" ]; then + WORKING_BRANCH=$(git_current_branch) + COMMON_ANCESTOR_COMMIT=`git merge-base ${BASE_BRANCH} ${WORKING_BRANCH}` + echo `git log ${COMMON_ANCESTOR_COMMIT}.. --pretty=oneline --grep="${PREFIX}"` + else + echo `git log --pretty=oneline --grep="${PREFIX}"` + fi +} + +parse_args() { + # parse options + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + # read arguments into global variables + BASE_BRANCH=$1 +} + +cmd_help() { + usage + exit 0 +} + diff --git a/git-now-rebase b/git-now-rebase old mode 100755 new mode 100644 index 6376624..0d28509 --- a/git-now-rebase +++ b/git-now-rebase @@ -1,66 +1,67 @@ -#!/bin/sh - -usage_exit() { - echo "Usage: git now rebase [-h] [-p] [-r remote] [base_branch] " 1>&2 - exit 1 +usage() { + echo "usage: git now rebase []" + echo " git now rebase --push|-p [--remote|-r ] []" } -# -# Options -# -while getopts "pr:h" GETOPTS -do - case $GETOPTS in - p) PUSH_FLAG=yes - ;; - r) REMOTE_NAME=$OPTARG - ;; - h) usage_exit - ;; - *) usage_exit - ;; - esac -done -shift $((OPTIND - 1)) -PREFIX="from now" -WORKING_BRANCH=`git branch -l | grep "*" | cut -d " " -f 2` +cmd_default() { + parse_args "$@" -if [ $# -eq 0 ] -then - FIRST_NOW_COMMIT=`git log --pretty=oneline --grep="${PREFIX}" | tail -n 1 | cut -d " " -f 1` - INITIAL_COMMIT=`git log --pretty=oneline | tail -n 1 | cut -d " " -f 1` + WORKING_BRANCH=$(git_current_branch) + INITIAL_COMMIT=$(git_now_initial_commit) - if [ ${FIRST_NOW_COMMIT} != ${INITIAL_COMMIT} ] - then - echo "git rebase -i ${FIRST_NOW_COMMIT}^" + if [ -n "$BASE_BRANCH" ]; then + COMMON_ANCESTOR_COMMIT=`git merge-base ${BASE_BRANCH} ${WORKING_BRANCH}` + FIRST_NOW_COMMIT=$(git_now_first_commit $COMMON_ANCESTOR_COMMIT) + + if [ "$FIRST_NOW_COMMIT" != "$INITIAL_COMMIT" ]; then + git rebase -i ${FIRST_NOW_COMMIT}^ + else + git checkout ${FIRST_NOW_COMMIT} + git commit --amend + git rebase --onto HEAD ${FIRST_NOW_COMMIT} ${WORKING_BRANCH} + fi else - echo "git checkout ${FIRST_NOW_COMMIT}" - echo "git commit --amend" - echo "git rebase --onto HEAD ${FIRST_NOW_COMMIT} ${WORKING_BRANCH}" + FIRST_NOW_COMMIT=$(git_now_first_commit) + + if [ "$FIRST_NOW_COMMIT" != "$INITIAL_COMMIT" ]; then + git rebase -i ${FIRST_NOW_COMMIT}^ + else + git checkout ${FIRST_NOW_COMMIT} + git commit --amend + git rebase --onto HEAD ${FIRST_NOW_COMMIT} ${WORKING_BRANCH} + fi fi -else + + if flag push; then + _cmd_push $WORKING_BRANCH $REMOTE + fi +} + +cmd_help() { + usage + exit 0 +} + +parse_args() { + # parse options + DEFINE_boolean 'push' false 'push to remote repository finally' 'p' + DEFINE_string 'remote' '' 'remote branch name to --set-upstream' 'r' + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + + # read arguments into global variables BASE_BRANCH=$1 - COMMON_ANCESTOR_COMMIT=`git merge-base ${BASE_BRANCH} ${WORKING_BRANCH}` - FIRST_NOW_COMMIT=`git log ${COMMON_ANCESTOR_COMMIT}.. --pretty=oneline --grep="${PREFIX}" | tail -n 1 | cut -d " " -f 1` - INITIAL_COMMIT=`git log --pretty=oneline | tail -n 1 | cut -d " " -f 1` + REMOTE=$FLAGS_remote +} - if [ ${FIRST_NOW_COMMIT} != ${INITIAL_COMMIT} ] - then - echo "git rebase -i ${FIRST_NOW_COMMIT}^" +_cmd_push() { + local branch=$1 + local remote=$2 + if [ -n "$remote" ]; then + git push --set-upstream ${remote} ${branch} else - echo "git checkout ${FIRST_NOW_COMMIT}" - echo "git commit --amend" - echo "git rebase --onto HEAD ${FIRST_NOW_COMMIT} ${WORKING_BRANCH}" + git push fi -fi +} -if [ $PUSH_FLAG ] -then - if [ $REMOTE_NAME ] - then - echo "git push --set-upstream ${WORKING_BRANCH} ${REMOTE_NAME}/${WORKING_BRANCH}" - else - echo "git push" - fi -fi diff --git a/git-now.rb b/git-now.rb index 2852ecd..d6f4229 100644 --- a/git-now.rb +++ b/git-now.rb @@ -1,7 +1,17 @@ require 'formula' -class GitNow < GithubGistFormula - url 'https://gist.github.com/raw/1167062/03c52077ce8c7fb72537bdf9cbd50bd11f3a9d5c/git-now' - md5 '72a36ca8deb21b7cc26b8a8f5dc3e7be' - homepage 'https://gist.github.com/1167062' +class GitNow < Formula + url 'https://github.com/nvie/gitflow.git', :tag => 'v0.0.1' + version '0.0.1' + head 'https://github.com/iwata/git-now.git', :branch => 'develop' + homepage 'https://github.com/iwata/git-now' + + # for longopt + depends_on 'gnu-getopt' + + def install + system "make", "prefix=#{prefix}", "install" + system "brew ln gnu-getopt" + end + end diff --git a/gitnow-common b/gitnow-common new file mode 100644 index 0000000..aec7aff --- /dev/null +++ b/gitnow-common @@ -0,0 +1,52 @@ +# +# Common functionality +# + +# shell output +warn() { echo "$@" >&2; } +die() { warn "$@"; exit 1; } + +escape() { + echo "$1" | sed 's/\([\.\+\$\*]\)/\\\1/g' +} + +# set logic +has() { + local item=$1; shift + echo " $@ " | grep -q " $(escape $item) " +} + +# basic math +min() { [ "$1" -le "$2" ] && echo "$1" || echo "$2"; } +max() { [ "$1" -ge "$2" ] && echo "$1" || echo "$2"; } + +# basic string matching +startswith() { [ "$1" != "${1#$2}" ]; } +endswith() { [ "$1" != "${1%$2}" ]; } + +# convenience functions for checking shFlags flags +flag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -eq $FLAGS_TRUE ]; } +noflag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -ne $FLAGS_TRUE ]; } + +# +# Git specific common functionality +# + +git_local_branches() { git branch --no-color | sed 's/^[* ] //'; } +git_remote_branches() { git branch -r --no-color | sed 's/^[* ] //'; } +git_all_branches() { ( git branch --no-color; git branch -r --no-color) | sed 's/^[* ] //'; } + +git_current_branch() { + git branch -l | grep "*" | cut -d " " -f 2 +} + +git_now_first_commit() { + local common=$1 + if [ $# -eq 1 ]; then + git log ${common}.. --pretty=oneline --grep="${PREFIX}" | tail -n 1 | cut -d " " -f 1 + else + git log --pretty=oneline --grep="${PREFIX}" | tail -n 1 | cut -d " " -f 1 + fi +} + +git_now_initial_commit() { git log --pretty=oneline | tail -n 1 | cut -d " " -f 1; } diff --git a/gitnow-shFlags b/gitnow-shFlags new file mode 120000 index 0000000..7b736c1 --- /dev/null +++ b/gitnow-shFlags @@ -0,0 +1 @@ +shFlags/src/shflags \ No newline at end of file diff --git a/shFlags b/shFlags new file mode 160000 index 0000000..2fb06af --- /dev/null +++ b/shFlags @@ -0,0 +1 @@ +Subproject commit 2fb06af13de884e9680f14a00c82e52a67c867f1 diff --git a/update b/update deleted file mode 100644 index dd2d168..0000000 --- a/update +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -PREFIX="from now" - -if [ ! "`git log --pretty=oneline $3 | head -n 1 | grep "${PREFIX}"`" ] -then - exit 0 -else - echo "error: There are tmp log messages in the received objects." 1>&2 - echo "error: Change these messages by 'git now --rebase'." 1>&2 - exit 1 -fi