Merge branch 'ph/parseopt-sh'

* ph/parseopt-sh:
  git-quiltimport.sh fix --patches handling
  git-am: -i does not take a string parameter.
  sh-setup: don't let eval output to be shell-expanded.
  git-sh-setup: fix parseopt `eval` string underquoting
  Give git-am back the ability to add Signed-off-by lines.
  git-rev-parse --parseopt
  scripts: Add placeholders for OPTIONS_SPEC
  Migrate git-repack.sh to use git-rev-parse --parseopt
  Migrate git-quiltimport.sh to use git-rev-parse --parseopt
  Migrate git-checkout.sh to use git-rev-parse --parseopt --keep-dashdash
  Migrate git-instaweb.sh to use git-rev-parse --parseopt
  Migrate git-merge.sh to use git-rev-parse --parseopt
  Migrate git-am.sh to use git-rev-parse --parseopt
  Migrate git-clone to use git-rev-parse --parseopt
  Migrate git-clean.sh to use git-rev-parse --parseopt.
  Update git-sh-setup(1) to allow transparent use of git-rev-parse --parseopt
  Add a parseopt mode to git-rev-parse to bring parse-options to shell scripts.
This commit is contained in:
Junio C Hamano 2007-11-17 21:39:37 -08:00
commit 9f4c4eb0e1
23 changed files with 540 additions and 322 deletions

View File

@ -23,6 +23,13 @@ distinguish between them.
OPTIONS OPTIONS
------- -------
--parseopt::
Use `git-rev-parse` in option parsing mode (see PARSEOPT section below).
--keep-dash-dash::
Only meaningful in `--parseopt` mode. Tells the option parser to echo
out the first `--` met instead of skipping it.
--revs-only:: --revs-only::
Do not output flags and parameters not meant for Do not output flags and parameters not meant for
`git-rev-list` command. `git-rev-list` command.
@ -288,10 +295,75 @@ Here are a handful examples:
C^@ I J F C^@ I J F
F^! D G H D F F^! D G H D F
PARSEOPT
--------
In `--parseopt` mode, `git-rev-parse` helps massaging options to bring to shell
scripts the same facilities C builtins have. It works as an option normalizer
(e.g. splits single switches aggregate values), a bit like `getopt(1)` does.
It takes on the standard input the specification of the options to parse and
understand, and echoes on the standard output a line suitable for `sh(1)` `eval`
to replace the arguments with normalized ones. In case of error, it outputs
usage on the standard error stream, and exits with code 129.
Input Format
~~~~~~~~~~~~
`git-rev-parse --parseopt` input format is fully text based. It has two parts,
separated by a line that contains only `--`. The lines before the separator
(should be more than one) are used for the usage.
The lines after the separator describe the options.
Each line of options has this format:
------------
<opt_spec><arg_spec>? SP+ help LF
------------
`<opt_spec>`::
its format is the short option character, then the long option name
separated by a comma. Both parts are not required, though at least one
is necessary. `h,help`, `dry-run` and `f` are all three correct
`<opt_spec>`.
`<arg_spec>`::
an `<arg_spec>` tells the option parser if the option has an argument
(`=`), an optional one (`?` though its use is discouraged) or none
(no `<arg_spec>` in that case).
The remainder of the line, after stripping the spaces, is used
as the help associated to the option.
Blank lines are ignored, and lines that don't match this specification are used
as option group headers (start the line with a space to create such
lines on purpose).
Example
~~~~~~~
------------
OPTS_SPEC="\
some-command [options] <args>...
some-command does foo and bar!
--
h,help show the help
foo some nifty option --foo
bar= some cool option --bar with an argument
An option group Header
C? option C with an optional argument"
eval `echo "$OPTS_SPEC" | git-rev-parse --parseopt -- "$@" || echo exit $?`
------------
Author Author
------ ------
Written by Linus Torvalds <torvalds@osdl.org> and Written by Linus Torvalds <torvalds@osdl.org> .
Junio C Hamano <junkio@cox.net> Junio C Hamano <junkio@cox.net> and Pierre Habouzit <madcoder@debian.org>
Documentation Documentation
-------------- --------------

View File

@ -8,6 +8,7 @@
#include "refs.h" #include "refs.h"
#include "quote.h" #include "quote.h"
#include "builtin.h" #include "builtin.h"
#include "parse-options.h"
#define DO_REVS 1 #define DO_REVS 1
#define DO_NOREV 2 #define DO_NOREV 2
@ -209,13 +210,138 @@ static int try_difference(const char *arg)
return 0; return 0;
} }
static int parseopt_dump(const struct option *o, const char *arg, int unset)
{
struct strbuf *parsed = o->value;
if (unset)
strbuf_addf(parsed, " --no-%s", o->long_name);
else if (o->short_name)
strbuf_addf(parsed, " -%c", o->short_name);
else
strbuf_addf(parsed, " --%s", o->long_name);
if (arg) {
strbuf_addch(parsed, ' ');
sq_quote_buf(parsed, arg);
}
return 0;
}
static const char *skipspaces(const char *s)
{
while (isspace(*s))
s++;
return s;
}
static int cmd_parseopt(int argc, const char **argv, const char *prefix)
{
static int keep_dashdash = 0;
static char const * const parseopt_usage[] = {
"git-rev-parse --parseopt [options] -- [<args>...]",
NULL
};
static struct option parseopt_opts[] = {
OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash,
"keep the `--` passed as an arg"),
OPT_END(),
};
struct strbuf sb, parsed;
const char **usage = NULL;
struct option *opts = NULL;
int onb = 0, osz = 0, unb = 0, usz = 0;
strbuf_init(&parsed, 0);
strbuf_addstr(&parsed, "set --");
argc = parse_options(argc, argv, parseopt_opts, parseopt_usage,
PARSE_OPT_KEEP_DASHDASH);
if (argc < 1 || strcmp(argv[0], "--"))
usage_with_options(parseopt_usage, parseopt_opts);
strbuf_init(&sb, 0);
/* get the usage up to the first line with a -- on it */
for (;;) {
if (strbuf_getline(&sb, stdin, '\n') == EOF)
die("premature end of input");
ALLOC_GROW(usage, unb + 1, usz);
if (!strcmp("--", sb.buf)) {
if (unb < 1)
die("no usage string given before the `--' separator");
usage[unb] = NULL;
break;
}
usage[unb++] = strbuf_detach(&sb, NULL);
}
/* parse: (<short>|<short>,<long>|<long>)[=?]? SP+ <help> */
while (strbuf_getline(&sb, stdin, '\n') != EOF) {
const char *s;
struct option *o;
if (!sb.len)
continue;
ALLOC_GROW(opts, onb + 1, osz);
memset(opts + onb, 0, sizeof(opts[onb]));
o = &opts[onb++];
s = strchr(sb.buf, ' ');
if (!s || *sb.buf == ' ') {
o->type = OPTION_GROUP;
o->help = xstrdup(skipspaces(s));
continue;
}
o->type = OPTION_CALLBACK;
o->help = xstrdup(skipspaces(s));
o->value = &parsed;
o->callback = &parseopt_dump;
switch (s[-1]) {
case '=':
s--;
break;
case '?':
o->flags = PARSE_OPT_OPTARG;
s--;
break;
default:
o->flags = PARSE_OPT_NOARG;
break;
}
if (s - sb.buf == 1) /* short option only */
o->short_name = *sb.buf;
else if (sb.buf[1] != ',') /* long option only */
o->long_name = xmemdupz(sb.buf, s - sb.buf);
else {
o->short_name = *sb.buf;
o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2);
}
}
strbuf_release(&sb);
/* put an OPT_END() */
ALLOC_GROW(opts, onb + 1, osz);
memset(opts + onb, 0, sizeof(opts[onb]));
argc = parse_options(argc, argv, opts, usage,
keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0);
strbuf_addf(&parsed, " --");
sq_quote_argv(&parsed, argv, argc, 0);
puts(parsed.buf);
return 0;
}
int cmd_rev_parse(int argc, const char **argv, const char *prefix) int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{ {
int i, as_is = 0, verify = 0; int i, as_is = 0, verify = 0;
unsigned char sha1[20]; unsigned char sha1[20];
git_config(git_default_config); if (argc > 1 && !strcmp("--parseopt", argv[1]))
return cmd_parseopt(argc - 1, argv + 1, prefix);
prefix = setup_git_directory();
git_config(git_default_config);
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
const char *arg = argv[i]; const char *arg = argv[i];

View File

@ -2,11 +2,26 @@
# #
# Copyright (c) 2005, 2006 Junio C Hamano # Copyright (c) 2005, 2006 Junio C Hamano
USAGE='[--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8] OPTIONS_KEEPDASHDASH=
[--3way] [--interactive] [--binary] OPTIONS_SPEC="\
[--whitespace=<option>] [-C<n>] [-p<n>] git-am [options] <mbox>|<Maildir>...
<mbox>|<Maildir>... git-am [options] --resolved
or, when resuming [--skip | --resolved]' git-am [options] --skip
--
d,dotest= use <dir> and not .dotest
i,interactive run interactively
b,binary pass --allo-binary-replacement to git-apply
3,3way allow fall back on 3way merging if needed
s,signoff add a Signed-off-by line to the commit message
u,utf8 recode into utf8 (default)
k,keep pass -k flagg to git-mailinfo
whitespace= pass it through git-apply
C= pass it through git-apply
p= pass it through git-apply
resolvemsg= override error message when patch failure occurs
r,resolved to be used after a patch failure
skip skip the current patch"
. git-sh-setup . git-sh-setup
set_reflog_action am set_reflog_action am
require_work_tree require_work_tree
@ -110,49 +125,38 @@ git_apply_opt=
while test $# != 0 while test $# != 0
do do
case "$1" in case "$1" in
-d=*|--d=*|--do=*|--dot=*|--dote=*|--dotes=*|--dotest=*) -i|--interactive)
dotest=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;; interactive=t ;;
-d|--d|--do|--dot|--dote|--dotes|--dotest) -b|--binary)
case "$#" in 1) usage ;; esac; shift binary=t ;;
dotest="$1"; shift;; -3|--3way)
threeway=t ;;
-i|--i|--in|--int|--inte|--inter|--intera|--interac|--interact|\ -s|--signoff)
--interacti|--interactiv|--interactive) sign=t ;;
interactive=t; shift ;; -u|--utf8)
utf8=t ;; # this is now default
-b|--b|--bi|--bin|--bina|--binar|--binary) --no-utf8)
binary=t; shift ;; utf8= ;;
-k|--keep)
-3|--3|--3w|--3wa|--3way) keep=t ;;
threeway=t; shift ;; -r|--resolved)
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff) resolved=t ;;
sign=t; shift ;; --skip)
-u|--u|--ut|--utf|--utf8) skip=t ;;
utf8=t; shift ;; # this is now default -d|--dotest)
--no-u|--no-ut|--no-utf|--no-utf8) shift; dotest=$1;;
utf8=; shift ;; --resolvemsg)
-k|--k|--ke|--kee|--keep) shift; resolvemsg=$1 ;;
keep=t; shift ;; --whitespace)
git_apply_opt="$git_apply_opt $1=$2"; shift ;;
-r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved) -C|-p)
resolved=t; shift ;; git_apply_opt="$git_apply_opt $1$2"; shift ;;
--sk|--ski|--skip)
skip=t; shift ;;
--whitespace=*|-C*|-p*)
git_apply_opt="$git_apply_opt $1"; shift ;;
--resolvemsg=*)
resolvemsg=${1#--resolvemsg=}; shift ;;
--) --)
shift; break ;; shift; break ;;
-*)
usage ;;
*) *)
break ;; usage ;;
esac esac
shift
done done
# If the dotest directory exists, but we have finished applying all the # If the dotest directory exists, but we have finished applying all the

View File

@ -22,6 +22,7 @@ git bisect log
git bisect run <cmd>... git bisect run <cmd>...
use <cmd>... to automatically bisect.' use <cmd>... to automatically bisect.'
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree

View File

@ -1,6 +1,16 @@
#!/bin/sh #!/bin/sh
USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]' OPTIONS_KEEPDASHDASH=t
OPTIONS_SPEC="\
git-branch [options] [<branch>] [<paths>...]
--
b= create a new branch started at <branch>
l create the new branchs reflog
track tells if the new branch should track the remote branch
f proceed even if the index or working tree is not HEAD
m performa three-way merge on local modifications if needed
q,quiet be quiet
"
SUBDIRECTORY_OK=Sometimes SUBDIRECTORY_OK=Sometimes
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree
@ -20,13 +30,12 @@ quiet=
v=-v v=-v
LF=' LF='
' '
while [ "$#" != "0" ]; do
arg="$1" while test $# != 0; do
shift case "$1" in
case "$arg" in -b)
"-b")
newbranch="$1"
shift shift
newbranch="$1"
[ -z "$newbranch" ] && [ -z "$newbranch" ] &&
die "git checkout: -b needs a branch name" die "git checkout: -b needs a branch name"
git show-ref --verify --quiet -- "refs/heads/$newbranch" && git show-ref --verify --quiet -- "refs/heads/$newbranch" &&
@ -34,64 +43,54 @@ while [ "$#" != "0" ]; do
git check-ref-format "heads/$newbranch" || git check-ref-format "heads/$newbranch" ||
die "git checkout: we do not like '$newbranch' as a branch name." die "git checkout: we do not like '$newbranch' as a branch name."
;; ;;
"-l") -l)
newbranch_log=-l newbranch_log=-l
;; ;;
"--track"|"--no-track") --track|--no-track)
track="$arg" track="$1"
;; ;;
"-f") -f)
force=1 force=1
;; ;;
-m) -m)
merge=1 merge=1
;; ;;
"-q") -q|--quiet)
quiet=1 quiet=1
v= v=
;; ;;
--) --)
shift
break break
;; ;;
-*)
usage
;;
*) *)
if rev=$(git rev-parse --verify "$arg^0" 2>/dev/null) usage
then
if [ -z "$rev" ]; then
echo "unknown flag $arg"
exit 1
fi
new_name="$arg"
if git show-ref --verify --quiet -- "refs/heads/$arg"
then
rev=$(git rev-parse --verify "refs/heads/$arg^0")
branch="$arg"
fi
new="$rev"
elif rev=$(git rev-parse --verify "$arg^{tree}" 2>/dev/null)
then
# checking out selected paths from a tree-ish.
new="$rev"
new_name="$arg^{tree}"
branch=
else
new=
new_name=
branch=
set x "$arg" "$@"
shift
fi
case "$1" in
--)
shift ;;
esac
break
;; ;;
esac esac
shift
done done
arg="$1"
if rev=$(git rev-parse --verify "$arg^0" 2>/dev/null)
then
[ -z "$rev" ] && die "unknown flag $arg"
new_name="$arg"
if git show-ref --verify --quiet -- "refs/heads/$arg"
then
rev=$(git rev-parse --verify "refs/heads/$arg^0")
branch="$arg"
fi
new="$rev"
shift
elif rev=$(git rev-parse --verify "$arg^{tree}" 2>/dev/null)
then
# checking out selected paths from a tree-ish.
new="$rev"
new_name="$arg^{tree}"
shift
fi
[ "$1" = "--" ] && shift
case "$newbranch,$track" in case "$newbranch,$track" in
,--*) ,--*)
die "git checkout: --track and --no-track require -b" die "git checkout: --track and --no-track require -b"
@ -138,8 +137,8 @@ Did you intend to checkout '$@' which can not be resolved as commit?"
git ls-files -- "$@" | git ls-files -- "$@" |
git checkout-index -f -u --stdin git checkout-index -f -u --stdin
# Run a post-checkout hook -- the HEAD does not change so the # Run a post-checkout hook -- the HEAD does not change so the
# current HEAD is passed in for both args # current HEAD is passed in for both args
if test -x "$GIT_DIR"/hooks/post-checkout; then if test -x "$GIT_DIR"/hooks/post-checkout; then
"$GIT_DIR"/hooks/post-checkout $old $old 0 "$GIT_DIR"/hooks/post-checkout $old $old 0
fi fi
@ -294,5 +293,5 @@ fi
# Run a post-checkout hook # Run a post-checkout hook
if test -x "$GIT_DIR"/hooks/post-checkout; then if test -x "$GIT_DIR"/hooks/post-checkout; then
"$GIT_DIR"/hooks/post-checkout $old $new 1 "$GIT_DIR"/hooks/post-checkout $old $new 1
fi fi

View File

@ -3,16 +3,22 @@
# Copyright (c) 2005-2006 Pavel Roskin # Copyright (c) 2005-2006 Pavel Roskin
# #
USAGE="[-d] [-f] [-n] [-q] [-x | -X] [--] <paths>..." OPTIONS_KEEPDASHDASH=
LONG_USAGE='Clean untracked files from the working directory OPTIONS_SPEC="\
-d remove directories as well git-clean [options] <paths>...
-f override clean.requireForce and clean anyway
-n don'\''t remove anything, just show what would be done Clean untracked files from the working directory
-q be quiet, only report errors
-x remove ignored files as well
-X remove only ignored files
When optional <paths>... arguments are given, the paths When optional <paths>... arguments are given, the paths
affected are further limited to those that match them.' affected are further limited to those that match them.
--
d remove directories as well
f override clean.requireForce and clean anyway
n don't remove anything, just show what would be done
q be quiet, only report errors
x remove ignored files as well
X remove only ignored files"
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree
@ -56,11 +62,9 @@ do
shift shift
break break
;; ;;
-*)
usage
;;
*) *)
break usage # should not happen
;;
esac esac
shift shift
done done
@ -77,9 +81,9 @@ case "$disabled" in
;; ;;
esac esac
case "$ignored,$ignoredonly" in if [ "$ignored,$ignoredonly" = "1,1" ]; then
1,1) usage;; die "-x and -X cannot be set together"
esac fi
if [ -z "$ignored" ]; then if [ -z "$ignored" ]; then
excl="--exclude-per-directory=.gitignore" excl="--exclude-per-directory=.gitignore"

View File

@ -8,15 +8,36 @@
# See git-sh-setup why. # See git-sh-setup why.
unset CDPATH unset CDPATH
OPTIONS_SPEC="\
git-clone [options] [--] <repo> [<dir>]
--
n,no-checkout don't create a checkout
bare create a bare repository
naked create a bare repository
l,local to clone from a local repository
no-hardlinks don't use local hardlinks, always copy
s,shared setup as a shared repository
template= path to the template directory
q,quiet be quiet
reference= reference repository
o,origin= use <name> instead of 'origin' to track upstream
u,upload-pack= path to git-upload-pack on the remote
depth= create a shallow clone of that depth
use-separate-remote compatibility, do not use
no-separate-remote compatibility, do not use"
die() { die() {
echo >&2 "$@" echo >&2 "$@"
exit 1 exit 1
} }
usage() { usage() {
die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] [--] <repo> [<dir>]" exec "$0" -h
} }
eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
get_repo_base() { get_repo_base() {
( (
cd "`/bin/pwd`" && cd "`/bin/pwd`" &&
@ -106,67 +127,57 @@ depth=
no_progress= no_progress=
local_explicitly_asked_for= local_explicitly_asked_for=
test -t 1 || no_progress=--no-progress test -t 1 || no_progress=--no-progress
while
case "$#,$1" in while test $# != 0
0,*) break ;; do
*,-n|*,--no|*,--no-|*,--no-c|*,--no-ch|*,--no-che|*,--no-chec|\ case "$1" in
*,--no-check|*,--no-checko|*,--no-checkou|*,--no-checkout) -n|--no-checkout)
no_checkout=yes ;; no_checkout=yes ;;
*,--na|*,--nak|*,--nake|*,--naked|\ --naked|--bare)
*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;; bare=yes ;;
*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) -l|--local)
local_explicitly_asked_for=yes local_explicitly_asked_for=yes
use_local_hardlink=yes ;; use_local_hardlink=yes
*,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\ ;;
*,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks) --no-hardlinks)
use_local_hardlink=no ;; use_local_hardlink=no ;;
*,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) -s|--shared)
local_shared=yes; ;; local_shared=yes ;;
1,--template) usage ;; --template)
*,--template)
shift; template="--template=$1" ;; shift; template="--template=$1" ;;
*,--template=*) -q|--quiet)
template="$1" ;; quiet=-q ;;
*,-q|*,--quiet) quiet=-q ;; --use-separate-remote|--no-separate-remote)
*,--use-separate-remote) ;;
*,--no-separate-remote)
die "clones are always made with separate-remote layout" ;; die "clones are always made with separate-remote layout" ;;
1,--reference) usage ;; --reference)
*,--reference)
shift; reference="$1" ;; shift; reference="$1" ;;
*,--reference=*) -o,--origin)
reference=`expr "z$1" : 'z--reference=\(.*\)'` ;; shift;
*,-o|*,--or|*,--ori|*,--orig|*,--origi|*,--origin) case "$1" in
case "$2" in
'') '')
usage ;; usage ;;
*/*) */*)
die "'$2' is not suitable for an origin name" die "'$1' is not suitable for an origin name"
esac esac
git check-ref-format "heads/$2" || git check-ref-format "heads/$1" ||
die "'$2' is not suitable for a branch name" die "'$1' is not suitable for a branch name"
test -z "$origin_override" || test -z "$origin_override" ||
die "Do not give more than one --origin options." die "Do not give more than one --origin options."
origin_override=yes origin_override=yes
origin="$2"; shift origin="$1"
;; ;;
1,-u|1,--upload-pack) usage ;; -u|--upload-pack)
*,-u|*,--upload-pack)
shift shift
upload_pack="--upload-pack=$1" ;; upload_pack="--upload-pack=$1" ;;
*,--upload-pack=*) --depth)
upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
1,--depth) usage;;
*,--depth)
shift shift
depth="--depth=$1";; depth="--depth=$1" ;;
*,--) --)
shift shift
break ;; break ;;
*,-*) usage ;; *)
*) break ;; usage ;;
esac esac
do
shift shift
done done

View File

@ -5,6 +5,7 @@
USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]' USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree

View File

@ -92,6 +92,7 @@ USAGE="[--env-filter <command>] [--tree-filter <command>] \
[--original <namespace>] [-d <directory>] [-f | --force] \ [--original <namespace>] [-d <directory>] [-f | --force] \
[<rev-list options>...]" [<rev-list options>...]"
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
git diff-files --quiet && git diff-files --quiet &&

View File

@ -2,9 +2,21 @@
# #
# Copyright (c) 2006 Eric Wong # Copyright (c) 2006 Eric Wong
# #
USAGE='[--start] [--stop] [--restart]
[--local] [--httpd=<httpd>] [--port=<port>] [--browser=<browser>] OPTIONS_KEEPDASHDASH=
[--module-path=<path> (for Apache2 only)]' OPTIONS_SPEC="\
git-instaweb [options] (--start | --stop | --restart)
--
l,local only bind on 127.0.0.1
p,port= the port to bind to
d,httpd= the command to launch
b,browser= the browser to launch
m,module-path= the module path (only needed for apache2)
Action
stop stop the web server
start start the web server
restart restart the web server
"
. git-sh-setup . git-sh-setup
@ -78,52 +90,26 @@ do
start_httpd start_httpd
exit 0 exit 0
;; ;;
--local|-l) -l|--local)
local=true local=true
;; ;;
-d|--httpd|--httpd=*) -d|--httpd)
case "$#,$1" in shift
*,*=*) httpd="$1"
httpd=`expr "$1" : '-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
httpd="$2"
shift ;;
esac
;; ;;
-b|--browser|--browser=*) -b|--browser)
case "$#,$1" in shift
*,*=*) browser="$1"
browser=`expr "$1" : '-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
browser="$2"
shift ;;
esac
;; ;;
-p|--port|--port=*) -p|--port)
case "$#,$1" in shift
*,*=*) port="$1"
port=`expr "$1" : '-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
port="$2"
shift ;;
esac
;; ;;
-m|--module-path=*|--module-path) -m|--module-path)
case "$#,$1" in shift
*,*=*) module_path="$1"
module_path=`expr "$1" : '-[^=]*=\(.*\)'` ;; ;;
1,*) --)
usage ;;
*)
module_path="$2"
shift ;;
esac
;; ;;
*) *)
usage usage

View File

@ -2,6 +2,7 @@
USAGE='' USAGE=''
SUBDIRECTORY_OK='Yes' SUBDIRECTORY_OK='Yes'
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
echo "WARNING: '$0' is deprecated in favor of 'git fsck --lost-found'" >&2 echo "WARNING: '$0' is deprecated in favor of 'git fsck --lost-found'" >&2

View File

@ -3,7 +3,19 @@
# Copyright (c) 2005 Junio C Hamano # Copyright (c) 2005 Junio C Hamano
# #
USAGE='[-n] [--summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s <strategy>] [-m=<merge-message>] <commit>+' OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-merge [options] <remote>...
git-merge [options] <msg> HEAD <remote>
--
summary show a diffstat at the end of the merge
n,no-summary don't show a diffstat at the end of the merge
squash create a single commit instead of doing a merge
commit perform a commit if the merge sucesses (default)
ff allow fast forward (default)
s,strategy= merge strategy to use
m,message= message to be used for the merge commit (if any)
"
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
. git-sh-setup . git-sh-setup
@ -132,72 +144,47 @@ merge_name () {
fi fi
} }
parse_option () {
case "$1" in
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
show_diffstat=false ;;
--summary)
show_diffstat=t ;;
--sq|--squ|--squa|--squas|--squash)
allow_fast_forward=t squash=t no_commit=t ;;
--no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
allow_fast_forward=t squash= no_commit= ;;
--c|--co|--com|--comm|--commi|--commit)
allow_fast_forward=t squash= no_commit= ;;
--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
allow_fast_forward=t squash= no_commit=t ;;
--ff)
allow_fast_forward=t squash= no_commit= ;;
--no-ff)
allow_fast_forward=false squash= no_commit= ;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
case "$#,$1" in
*,*=*)
strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
1,*)
usage ;;
*)
strategy="$2"
shift ;;
esac
case " $all_strategies " in
*" $strategy "*)
use_strategies="$use_strategies$strategy " ;;
*)
die "available strategies are: $all_strategies" ;;
esac
;;
-m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
merge_msg=`expr "z$1" : 'z-[^=]*=\(.*\)'`
have_message=t
;;
-m|--m|--me|--mes|--mess|--messa|--messag|--message)
shift
case "$#" in
1) usage ;;
esac
merge_msg="$1"
have_message=t
;;
-*) usage ;;
*) return 1 ;;
esac
shift
args_left=$#
}
parse_config () { parse_config () {
while test $# -gt 0 while test $# != 0; do
do case "$1" in
parse_option "$@" || usage -n|--no-summary)
while test $args_left -lt $# show_diffstat=false ;;
do --summary)
show_diffstat=t ;;
--squash)
allow_fast_forward=t squash=t no_commit=t ;;
--no-squash)
allow_fast_forward=t squash= no_commit= ;;
--commit)
allow_fast_forward=t squash= no_commit= ;;
--no-commit)
allow_fast_forward=t squash= no_commit=t ;;
--ff)
allow_fast_forward=t squash= no_commit= ;;
--no-ff)
allow_fast_forward=false squash= no_commit= ;;
-s|--strategy)
shift shift
done case " $all_strategies " in
*" $1 "*)
use_strategies="$use_strategies$1 " ;;
*)
die "available strategies are: $all_strategies" ;;
esac
;;
-m|--message)
shift
merge_msg="$1"
have_message=t
;;
--)
shift
break ;;
*) usage ;;
esac
shift
done done
args_left=$#
} }
test $# != 0 || usage test $# != 0 || usage
@ -209,17 +196,12 @@ then
mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions") mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions")
if test -n "$mergeopts" if test -n "$mergeopts"
then then
parse_config $mergeopts parse_config $mergeopts --
fi fi
fi fi
while parse_option "$@" parse_config "$@"
do while test $args_left -lt $#; do shift; done
while test $args_left -lt $#
do
shift
done
done
if test -z "$show_diffstat"; then if test -z "$show_diffstat"; then
test "$(git config --bool merge.diffstat)" = false && show_diffstat=false test "$(git config --bool merge.diffstat)" = false && show_diffstat=false

View File

@ -10,6 +10,7 @@
USAGE='[--tool=tool] [file to merge] ...' USAGE='[--tool=tool] [file to merge] ...'
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree
prefix=$(git rev-parse --show-prefix) prefix=$(git rev-parse --show-prefix)

View File

@ -7,6 +7,7 @@
USAGE='[-n | --no-summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...' USAGE='[-n | --no-summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.' LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
set_reflog_action "pull $*" set_reflog_action "pull $*"
require_work_tree require_work_tree

View File

@ -1,5 +1,12 @@
#!/bin/sh #!/bin/sh
USAGE='--dry-run --author <author> --patches </path/to/quilt/patch/directory>' OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-quiltimport [options]
--
n,dry-run dry run
author= author name and email address for patches without any
patches= path to the quilt series and patches
"
SUBDIRECTORY_ON=Yes SUBDIRECTORY_ON=Yes
. git-sh-setup . git-sh-setup
@ -8,39 +15,25 @@ quilt_author=""
while test $# != 0 while test $# != 0
do do
case "$1" in case "$1" in
--au=*|--aut=*|--auth=*|--autho=*|--author=*) --author)
quilt_author=$(expr "z$1" : 'z-[^=]*\(.*\)')
shift
;;
--au|--aut|--auth|--autho|--author)
case "$#" in 1) usage ;; esac
shift shift
quilt_author="$1" quilt_author="$1"
shift
;; ;;
-n|--dry-run)
--dry-run)
shift
dry_run=1 dry_run=1
;; ;;
--patches)
--pa=*|--pat=*|--patc=*|--patch=*|--patche=*|--patches=*)
QUILT_PATCHES=$(expr "z$1" : 'z-[^=]*\(.*\)')
shift
;;
--pa|--pat|--patc|--patch|--patche|--patches)
case "$#" in 1) usage ;; esac
shift shift
QUILT_PATCHES="$1" QUILT_PATCHES="$1"
shift
;; ;;
--)
shift
break;;
*) *)
break usage
;; ;;
esac esac
shift
done done
# Quilt Author # Quilt Author

View File

@ -13,6 +13,7 @@
USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose] USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose]
[--onto <branch>] <upstream> [<branch>])' [--onto <branch>] <upstream> [<branch>])'
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree

View File

@ -29,6 +29,7 @@ Example: git-rebase master~1 topic
' '
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
set_reflog_action rebase set_reflog_action rebase
require_work_tree require_work_tree

View File

@ -3,7 +3,22 @@
# Copyright (c) 2005 Linus Torvalds # Copyright (c) 2005 Linus Torvalds
# #
USAGE='[-a|-A] [-d] [-f] [-l] [-n] [-q] [--max-pack-size=N] [--window=N] [--window-memory=N] [--depth=N]' OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git-repack [options]
--
a pack everything in a single pack
A same as -a, and keep unreachable objects too
d remove redundant packs, and run git-prune-packed
f pass --no-reuse-delta to git-pack-objects
q,quiet be quiet
l pass --local to git-pack-objects
Packing constraints
window= size of the window used for delta compression
window-memory= same as the above, but limit memory size instead of entries count
depth= limits the maximum delta depth
max-pack-size= maximum size of each packfile
"
SUBDIRECTORY_OK='Yes' SUBDIRECTORY_OK='Yes'
. git-sh-setup . git-sh-setup
@ -20,10 +35,9 @@ do
-q) quiet=-q ;; -q) quiet=-q ;;
-f) no_reuse=--no-reuse-object ;; -f) no_reuse=--no-reuse-object ;;
-l) local=--local ;; -l) local=--local ;;
--max-pack-size=*) extra="$extra $1" ;; --max-pack-size|--window|--window-memory|--depth)
--window=*) extra="$extra $1" ;; extra="$extra $1=$2"; shift ;;
--window-memory=*) extra="$extra $1" ;; --) shift; break;;
--depth=*) extra="$extra $1" ;;
*) usage ;; *) usage ;;
esac esac
shift shift

View File

@ -8,6 +8,7 @@ USAGE='<commit> <url> [<head>]'
LONG_USAGE='Summarizes the changes since <commit> to the standard output, LONG_USAGE='Summarizes the changes since <commit> to the standard output,
and includes <url> in the message generated.' and includes <url> in the message generated.'
SUBDIRECTORY_OK='Yes' SUBDIRECTORY_OK='Yes'
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
. git-parse-remote . git-parse-remote

View File

@ -16,9 +16,40 @@ die() {
exit 1 exit 1
} }
usage() { if test -n "$OPTIONS_SPEC"; then
die "Usage: $0 $USAGE" usage() {
} exec "$0" -h
}
parseopt_extra=
[ -n "$OPTIONS_KEEPDASHDASH" ] &&
parseopt_extra="--keep-dashdash"
eval "$(
echo "$OPTIONS_SPEC" |
git rev-parse --parseopt $parseopt_extra -- "$@" ||
echo exit $?
)"
else
usage() {
die "Usage: $0 $USAGE"
}
if [ -z "$LONG_USAGE" ]
then
LONG_USAGE="Usage: $0 $USAGE"
else
LONG_USAGE="Usage: $0 $USAGE
$LONG_USAGE"
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "$LONG_USAGE"
exit
esac
fi
set_reflog_action() { set_reflog_action() {
if [ -z "${GIT_REFLOG_ACTION:+set}" ] if [ -z "${GIT_REFLOG_ACTION:+set}" ]
@ -91,21 +122,6 @@ get_author_ident_from_commit () {
LANG=C LC_ALL=C sed -ne "$pick_author_script" LANG=C LC_ALL=C sed -ne "$pick_author_script"
} }
if [ -z "$LONG_USAGE" ]
then
LONG_USAGE="Usage: $0 $USAGE"
else
LONG_USAGE="Usage: $0 $USAGE
$LONG_USAGE"
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "$LONG_USAGE"
exit
esac
# Make sure we are in a valid repository of a vintage we understand. # Make sure we are in a valid repository of a vintage we understand.
if [ -z "$SUBDIRECTORY_OK" ] if [ -z "$SUBDIRECTORY_OK" ]
then then

View File

@ -4,6 +4,7 @@
USAGE='[ | list | show | apply | clear]' USAGE='[ | list | show | apply | clear]'
SUBDIRECTORY_OK=Yes SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree
cd_to_toplevel cd_to_toplevel

View File

@ -5,6 +5,7 @@
# Copyright (c) 2007 Lars Hjemli # Copyright (c) 2007 Lars Hjemli
USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]' USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
OPTIONS_SPEC=
. git-sh-setup . git-sh-setup
require_work_tree require_work_tree

2
git.c
View File

@ -338,7 +338,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "rerere", cmd_rerere, RUN_SETUP }, { "rerere", cmd_rerere, RUN_SETUP },
{ "reset", cmd_reset, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP },
{ "rev-list", cmd_rev_list, RUN_SETUP }, { "rev-list", cmd_rev_list, RUN_SETUP },
{ "rev-parse", cmd_rev_parse, RUN_SETUP }, { "rev-parse", cmd_rev_parse },
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE }, { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
{ "rm", cmd_rm, RUN_SETUP }, { "rm", cmd_rm, RUN_SETUP },
{ "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE }, { "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },