mirror of
https://github.com/git/git.git
synced 2026-03-14 02:43:25 +01:00
Merge commit 'v1.5.6.1' into devel
Conflicts: RelNotes cache.h
This commit is contained in:
28
Documentation/RelNotes-1.5.6.1.txt
Normal file
28
Documentation/RelNotes-1.5.6.1.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
GIT v1.5.6.1 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.5.6
|
||||
------------------
|
||||
|
||||
* Last minute change broke loose object creation on AIX.
|
||||
|
||||
* (performance fix) We used to make $GIT_DIR absolute path early in the
|
||||
programs but keeping it relative to the current directory internally
|
||||
gives 1-3 per-cent performance boost.
|
||||
|
||||
* bash completion knows the new --graph option to git-log family.
|
||||
|
||||
|
||||
* git-diff -c/--cc showed unnecessary "deletion" lines at the context
|
||||
boundary.
|
||||
|
||||
* git-for-each-ref ignored %(object) and %(type) requests for tag
|
||||
objects.
|
||||
|
||||
* git-merge usage had a typo.
|
||||
|
||||
* Rebuilding of git-svn metainfo database did not take rewriteRoot
|
||||
option into account.
|
||||
|
||||
* Running "git-rebase --continue/--skip/--abort" before starting a
|
||||
rebase gave nonsense error messages.
|
||||
@@ -448,6 +448,8 @@ svn-remote.<name>.rewriteRoot::
|
||||
the repository with a public http:// or svn:// URL in the
|
||||
metadata so users of it will see the public URL.
|
||||
|
||||
--
|
||||
|
||||
Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps
|
||||
options all affect the metadata generated and used by git-svn; they
|
||||
*must* be set in the configuration file before any history is imported
|
||||
@@ -456,7 +458,6 @@ and these settings should never be changed once they are set.
|
||||
Additionally, only one of these four options can be used per-svn-remote
|
||||
section because they affect the 'git-svn-id:' metadata line.
|
||||
|
||||
--
|
||||
|
||||
BASIC EXAMPLES
|
||||
--------------
|
||||
|
||||
@@ -43,12 +43,13 @@ unreleased) version of git, that is available from 'master'
|
||||
branch of the `git.git` repository.
|
||||
Documentation for older releases are available here:
|
||||
|
||||
* link:v1.5.6/git.html[documentation for release 1.5.6]
|
||||
* link:v1.5.6.1/git.html[documentation for release 1.5.6.1]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes-1.5.6.txt[1.5.6],
|
||||
link:RelNotes-1.5.6.1.txt[1.5.6.1].
|
||||
link:RelNotes-1.5.6.txt[1.5.6].
|
||||
|
||||
* link:v1.5.5/git.html[documentation for release 1.5.5]
|
||||
* link:v1.5.5.4/git.html[documentation for release 1.5.5.4]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes-1.5.5.4.txt[1.5.5.4],
|
||||
@@ -57,8 +58,6 @@ Documentation for older releases are available here:
|
||||
link:RelNotes-1.5.5.1.txt[1.5.5.1],
|
||||
link:RelNotes-1.5.5.txt[1.5.5].
|
||||
|
||||
* link:v1.5.5.4/git.html[documentation for release 1.5.5.4]
|
||||
|
||||
* link:v1.5.4.5/git.html[documentation for release 1.5.4.5]
|
||||
|
||||
* release notes for
|
||||
@@ -82,6 +81,8 @@ Documentation for older releases are available here:
|
||||
link:RelNotes-1.5.3.1.txt[1.5.3.1],
|
||||
link:RelNotes-1.5.3.txt[1.5.3].
|
||||
|
||||
* link:v1.5.2.5/git.html[documentation for release 1.5.2.5]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes-1.5.2.5.txt[1.5.2.5],
|
||||
link:RelNotes-1.5.2.4.txt[1.5.2.4],
|
||||
|
||||
@@ -68,7 +68,7 @@ function info {
|
||||
# - Branches should only be fast-forwarded.
|
||||
case "$1" in
|
||||
refs/tags/*)
|
||||
[ -f "$GIT_DIR/$1" ] &&
|
||||
git rev-parse --verify -q "$1" &&
|
||||
deny >/dev/null "You can't overwrite an existing tag"
|
||||
;;
|
||||
refs/heads/*)
|
||||
|
||||
@@ -4,7 +4,7 @@ builtin API
|
||||
Adding a new built-in
|
||||
---------------------
|
||||
|
||||
There are 4 things to do to add a bulit-in command implementation to
|
||||
There are 4 things to do to add a built-in command implementation to
|
||||
git:
|
||||
|
||||
. Define the implementation of the built-in command `foo` with
|
||||
@@ -18,8 +18,8 @@ git:
|
||||
defined in `git.c`. The entry should look like:
|
||||
|
||||
{ "foo", cmd_foo, <options> },
|
||||
|
||||
where options is the bitwise-or of:
|
||||
+
|
||||
where options is the bitwise-or of:
|
||||
|
||||
`RUN_SETUP`::
|
||||
|
||||
@@ -33,6 +33,12 @@ git:
|
||||
If the standard output is connected to a tty, spawn a pager and
|
||||
feed our output to it.
|
||||
|
||||
`NEED_WORK_TREE`::
|
||||
|
||||
Make sure there is a work tree, i.e. the command cannot act
|
||||
on bare repositories.
|
||||
This makes only sense when `RUN_SETUP` is also set.
|
||||
|
||||
. Add `builtin-foo.o` to `BUILTIN_OBJS` in `Makefile`.
|
||||
|
||||
Additionally, if `foo` is a new command, there are 3 more things to do:
|
||||
@@ -41,8 +47,7 @@ Additionally, if `foo` is a new command, there are 3 more things to do:
|
||||
|
||||
. Write documentation in `Documentation/git-foo.txt`.
|
||||
|
||||
. Add an entry for `git-foo` to the list at the end of
|
||||
`Documentation/cmd-list.perl`.
|
||||
. Add an entry for `git-foo` to `command-list.txt`.
|
||||
|
||||
|
||||
How a built-in is called
|
||||
|
||||
@@ -1,6 +1,206 @@
|
||||
parse-options API
|
||||
=================
|
||||
|
||||
Talk about <parse-options.h>
|
||||
The parse-options API is used to parse and massage options in git
|
||||
and to provide a usage help with consistent look.
|
||||
|
||||
(Pierre)
|
||||
Basics
|
||||
------
|
||||
|
||||
The argument vector `argv[]` may usually contain mandatory or optional
|
||||
'non-option arguments', e.g. a filename or a branch, and 'options'.
|
||||
Options are optional arguments that start with a dash and
|
||||
that allow to change the behavior of a command.
|
||||
|
||||
* There are basically three types of options:
|
||||
'boolean' options,
|
||||
options with (mandatory) 'arguments' and
|
||||
options with 'optional arguments'
|
||||
(i.e. a boolean option that can be adjusted).
|
||||
|
||||
* There are basically two forms of options:
|
||||
'Short options' consist of one dash (`-`) and one alphanumeric
|
||||
character.
|
||||
'Long options' begin with two dashes (`\--`) and some
|
||||
alphanumeric characters.
|
||||
|
||||
* Options are case-sensitive.
|
||||
Please define 'lower-case long options' only.
|
||||
|
||||
The parse-options API allows:
|
||||
|
||||
* 'sticked' and 'separate form' of options with arguments.
|
||||
`-oArg` is sticked, `-o Arg` is separate form.
|
||||
`\--option=Arg` is sticked, `\--option Arg` is separate form.
|
||||
|
||||
* Long options may be 'abbreviated', as long as the abbreviation
|
||||
is unambiguous.
|
||||
|
||||
* Short options may be bundled, e.g. `-a -b` can be specified as `-ab`.
|
||||
|
||||
* Boolean long options can be 'negated' (or 'unset') by prepending
|
||||
`no-`, e.g. `\--no-abbrev` instead of `\--abbrev`.
|
||||
|
||||
* Options and non-option arguments can clearly be separated using the `\--`
|
||||
option, e.g. `-a -b \--option \-- \--this-is-a-file` indicates that
|
||||
`\--this-is-a-file` must not be processed as an option.
|
||||
|
||||
Steps to parse options
|
||||
----------------------
|
||||
|
||||
. `#include "parse-options.h"`
|
||||
|
||||
. define a NULL-terminated
|
||||
`static const char * const builtin_foo_usage[]` array
|
||||
containing alternative usage strings
|
||||
|
||||
. define `builtin_foo_options` array as described below
|
||||
in section 'Data Structure'.
|
||||
|
||||
. in `cmd_foo(int argc, const char **argv, const char *prefix)`
|
||||
call
|
||||
|
||||
argc = parse_options(argc, argv, builtin_foo_options, builtin_foo_usage, flags);
|
||||
+
|
||||
`parse_options()` will filter out the processed options of `argv[]` and leave the
|
||||
non-option arguments in `argv[]`.
|
||||
`argc` is updated appropriately because of the assignment.
|
||||
+
|
||||
Flags are the bitwise-or of:
|
||||
|
||||
`PARSE_OPT_KEEP_DASHDASH`::
|
||||
Keep the `\--` that usually separates options from
|
||||
non-option arguments.
|
||||
|
||||
`PARSE_OPT_STOP_AT_NON_OPTION`::
|
||||
Usually the whole argument vector is massaged and reordered.
|
||||
Using this flag, processing is stopped at the first non-option
|
||||
argument.
|
||||
|
||||
Data Structure
|
||||
--------------
|
||||
|
||||
The main data structure is an array of the `option` struct,
|
||||
say `static struct option builtin_add_options[]`.
|
||||
There are some macros to easily define options:
|
||||
|
||||
`OPT__ABBREV(&int_var)`::
|
||||
Add `\--abbrev[=<n>]`.
|
||||
|
||||
`OPT__DRY_RUN(&int_var)`::
|
||||
Add `-n, \--dry-run`.
|
||||
|
||||
`OPT__QUIET(&int_var)`::
|
||||
Add `-q, \--quiet`.
|
||||
|
||||
`OPT__VERBOSE(&int_var)`::
|
||||
Add `-v, \--verbose`.
|
||||
|
||||
`OPT_GROUP(description)`::
|
||||
Start an option group. `description` is a short string that
|
||||
describes the group or an empty string.
|
||||
Start the description with an upper-case letter.
|
||||
|
||||
`OPT_BOOLEAN(short, long, &int_var, description)`::
|
||||
Introduce a boolean option.
|
||||
`int_var` is incremented on each use.
|
||||
|
||||
`OPT_BIT(short, long, &int_var, description, mask)`::
|
||||
Introduce a boolean option.
|
||||
If used, `int_var` is bitwise-ored with `mask`.
|
||||
|
||||
`OPT_SET_INT(short, long, &int_var, description, integer)`::
|
||||
Introduce a boolean option.
|
||||
If used, set `int_var` to `integer`.
|
||||
|
||||
`OPT_SET_PTR(short, long, &ptr_var, description, ptr)`::
|
||||
Introduce a boolean option.
|
||||
If used, set `ptr_var` to `ptr`.
|
||||
|
||||
`OPT_STRING(short, long, &str_var, arg_str, description)`::
|
||||
Introduce an option with string argument.
|
||||
The string argument is put into `str_var`.
|
||||
|
||||
`OPT_INTEGER(short, long, &int_var, description)`::
|
||||
Introduce an option with integer argument.
|
||||
The integer is put into `int_var`.
|
||||
|
||||
`OPT_DATE(short, long, &int_var, description)`::
|
||||
Introduce an option with date argument, see `approxidate()`.
|
||||
The timestamp is put into `int_var`.
|
||||
|
||||
`OPT_CALLBACK(short, long, &var, arg_str, description, func_ptr)`::
|
||||
Introduce an option with argument.
|
||||
The argument will be fed into the function given by `func_ptr`
|
||||
and the result will be put into `var`.
|
||||
See 'Option Callbacks' below for a more elaborate description.
|
||||
|
||||
`OPT_ARGUMENT(long, description)`::
|
||||
Introduce a long-option argument that will be kept in `argv[]`.
|
||||
|
||||
|
||||
The last element of the array must be `OPT_END()`.
|
||||
|
||||
If not stated otherwise, interpret the arguments as follows:
|
||||
|
||||
* `short` is a character for the short option
|
||||
(e.g. `\'e\'` for `-e`, use `0` to omit),
|
||||
|
||||
* `long` is a string for the long option
|
||||
(e.g. `"example"` for `\--example`, use `NULL` to omit),
|
||||
|
||||
* `int_var` is an integer variable,
|
||||
|
||||
* `str_var` is a string variable (`char *`),
|
||||
|
||||
* `arg_str` is the string that is shown as argument
|
||||
(e.g. `"branch"` will result in `<branch>`).
|
||||
If set to `NULL`, three dots (`...`) will be displayed.
|
||||
|
||||
* `description` is a short string to describe the effect of the option.
|
||||
It shall begin with a lower-case letter and a full stop (`.`) shall be
|
||||
omitted at the end.
|
||||
|
||||
Option Callbacks
|
||||
----------------
|
||||
|
||||
The function must be defined in this form:
|
||||
|
||||
int func(const struct option *opt, const char *arg, int unset)
|
||||
|
||||
The callback mechanism is as follows:
|
||||
|
||||
* Inside `funct`, the only interesting member of the structure
|
||||
given by `opt` is the void pointer `opt->value`.
|
||||
`\*opt->value` will be the value that is saved into `var`, if you
|
||||
use `OPT_CALLBACK()`.
|
||||
For example, do `*(unsigned long *)opt->value = 42;` to get 42
|
||||
into an `unsigned long` variable.
|
||||
|
||||
* Return value `0` indicates success and non-zero return
|
||||
value will invoke `usage_with_options()` and, thus, die.
|
||||
|
||||
* If the user negates the option, `arg` is `NULL` and `unset` is 1.
|
||||
|
||||
Sophisticated option parsing
|
||||
----------------------------
|
||||
|
||||
If you need, for example, option callbacks with optional arguments
|
||||
or without arguments at all, or if you need other special cases,
|
||||
that are not handled by the macros above, you need to specify the
|
||||
members of the `option` structure manually.
|
||||
|
||||
This is not covered in this document, but well documented
|
||||
in `parse-options.h` itself.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
See `test-parse-options.c` and
|
||||
`builtin-add.c`,
|
||||
`builtin-clone.c`,
|
||||
`builtin-commit.c`,
|
||||
`builtin-fetch.c`,
|
||||
`builtin-fsck.c`,
|
||||
`builtin-rm.c`
|
||||
for real-world examples.
|
||||
|
||||
@@ -400,6 +400,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (!option_bare) {
|
||||
junk_work_tree = work_tree;
|
||||
if (safe_create_leading_directories_const(work_tree) < 0)
|
||||
die("could not create leading directories of '%s'",
|
||||
work_tree);
|
||||
if (mkdir(work_tree, 0755))
|
||||
die("could not create work tree dir '%s'.", work_tree);
|
||||
set_git_work_tree(work_tree);
|
||||
@@ -410,6 +413,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
|
||||
setenv(CONFIG_ENVIRONMENT, xstrdup(mkpath("%s/config", git_dir)), 1);
|
||||
|
||||
if (safe_create_leading_directories_const(git_dir) < 0)
|
||||
die("could not create leading directories of '%s'", git_dir);
|
||||
set_git_dir(make_absolute_path(git_dir));
|
||||
|
||||
fprintf(stderr, "Initialize %s\n", git_dir);
|
||||
|
||||
@@ -234,6 +234,13 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob
|
||||
name++;
|
||||
if (!strcmp(name, "tag"))
|
||||
v->s = tag->tag;
|
||||
else if (!strcmp(name, "type") && tag->tagged)
|
||||
v->s = typename(tag->tagged->type);
|
||||
else if (!strcmp(name, "object") && tag->tagged) {
|
||||
char *s = xmalloc(41);
|
||||
strcpy(s, sha1_to_hex(tag->tagged->sha1));
|
||||
v->s = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -481,15 +481,6 @@ static char *unique_path(const char *path, const char *branch)
|
||||
return newpath;
|
||||
}
|
||||
|
||||
static int mkdir_p(const char *path, unsigned long mode)
|
||||
{
|
||||
/* path points to cache entries, so xstrdup before messing with it */
|
||||
char *buf = xstrdup(path);
|
||||
int result = safe_create_leading_directories(buf);
|
||||
free(buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void flush_buffer(int fd, const char *buf, unsigned long size)
|
||||
{
|
||||
while (size > 0) {
|
||||
@@ -512,7 +503,7 @@ static int make_room_for_path(const char *path)
|
||||
int status;
|
||||
const char *msg = "failed to create path '%s'%s";
|
||||
|
||||
status = mkdir_p(path, 0777);
|
||||
status = safe_create_leading_directories_const(path);
|
||||
if (status) {
|
||||
if (status == -3) {
|
||||
/* something else exists */
|
||||
@@ -583,7 +574,7 @@ static void update_file_flags(const unsigned char *sha,
|
||||
close(fd);
|
||||
} else if (S_ISLNK(mode)) {
|
||||
char *lnk = xmemdupz(buf, size);
|
||||
mkdir_p(path, 0777);
|
||||
safe_create_leading_directories_const(path);
|
||||
unlink(path);
|
||||
symlink(lnk, path);
|
||||
free(lnk);
|
||||
|
||||
2
cache.h
2
cache.h
@@ -518,6 +518,7 @@ enum sharedrepo {
|
||||
int git_config_perm(const char *var, const char *value);
|
||||
int adjust_shared_perm(const char *path);
|
||||
int safe_create_leading_directories(char *path);
|
||||
int safe_create_leading_directories_const(const char *path);
|
||||
char *enter_repo(char *path, int strict);
|
||||
static inline int is_absolute_path(const char *path)
|
||||
{
|
||||
@@ -525,6 +526,7 @@ static inline int is_absolute_path(const char *path)
|
||||
}
|
||||
const char *make_absolute_path(const char *path);
|
||||
const char *make_nonrelative_path(const char *path);
|
||||
const char *make_relative_path(const char *abs, const char *base);
|
||||
/* Convert slashes in place. On Windows to backslashes. */
|
||||
char *make_native_separator(char *path);
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ struct sline {
|
||||
/* bit 0 up to (N-1) are on if the parent has this line (i.e.
|
||||
* we did not change it).
|
||||
* bit N is used for "interesting" lines, including context.
|
||||
* bit (N+1) is used for "do not show deletion before this".
|
||||
*/
|
||||
unsigned long flag;
|
||||
unsigned long *p_lno;
|
||||
@@ -308,6 +309,7 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent)
|
||||
{
|
||||
unsigned long all_mask = (1UL<<num_parent) - 1;
|
||||
unsigned long mark = (1UL<<num_parent);
|
||||
unsigned long no_pre_delete = (2UL<<num_parent);
|
||||
unsigned long i;
|
||||
|
||||
/* Two groups of interesting lines may have a short gap of
|
||||
@@ -329,7 +331,7 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent)
|
||||
|
||||
/* Paint a few lines before the first interesting line. */
|
||||
while (j < i)
|
||||
sline[j++].flag |= mark;
|
||||
sline[j++].flag |= mark | no_pre_delete;
|
||||
|
||||
again:
|
||||
/* we know up to i is to be included. where does the
|
||||
@@ -502,6 +504,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
|
||||
int use_color)
|
||||
{
|
||||
unsigned long mark = (1UL<<num_parent);
|
||||
unsigned long no_pre_delete = (2UL<<num_parent);
|
||||
int i;
|
||||
unsigned long lno = 0;
|
||||
const char *c_frag = diff_get_color(use_color, DIFF_FRAGINFO);
|
||||
@@ -581,7 +584,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
|
||||
int j;
|
||||
unsigned long p_mask;
|
||||
sl = &sline[lno++];
|
||||
ll = sl->lost_head;
|
||||
ll = (sl->flag & no_pre_delete) ? NULL : sl->lost_head;
|
||||
while (ll) {
|
||||
fputs(c_old, stdout);
|
||||
for (j = 0; j < num_parent; j++) {
|
||||
|
||||
@@ -761,6 +761,7 @@ _git_log ()
|
||||
--pretty= --name-status --name-only --raw
|
||||
--not --all
|
||||
--left-right --cherry-pick
|
||||
--graph
|
||||
"
|
||||
return
|
||||
;;
|
||||
|
||||
@@ -13,7 +13,7 @@ n don't show a diffstat at the end of the merge
|
||||
summary (synonym to --stat)
|
||||
log add list of one-line log to merge commit message
|
||||
squash create a single commit instead of doing a merge
|
||||
commit perform a commit if the merge sucesses (default)
|
||||
commit perform a commit if the merge succeeds (default)
|
||||
ff allow fast forward (default)
|
||||
s,strategy= merge strategy to use
|
||||
m,message= message to be used for the merge commit (if any)
|
||||
|
||||
@@ -150,6 +150,9 @@ while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
--continue)
|
||||
test -d "$dotest" -o -d .dotest ||
|
||||
die "No rebase in progress?"
|
||||
|
||||
git diff-files --quiet --ignore-submodules || {
|
||||
echo "You must edit all merge conflicts and then"
|
||||
echo "mark them as resolved using git add"
|
||||
@@ -178,6 +181,9 @@ do
|
||||
exit
|
||||
;;
|
||||
--skip)
|
||||
test -d "$dotest" -o -d .dotest ||
|
||||
die "No rebase in progress?"
|
||||
|
||||
git reset --hard HEAD || exit $?
|
||||
if test -d "$dotest"
|
||||
then
|
||||
@@ -203,16 +209,16 @@ do
|
||||
exit
|
||||
;;
|
||||
--abort)
|
||||
test -d "$dotest" -o -d .dotest ||
|
||||
die "No rebase in progress?"
|
||||
|
||||
git rerere clear
|
||||
if test -d "$dotest"
|
||||
then
|
||||
move_to_original_branch
|
||||
elif test -d .dotest
|
||||
then
|
||||
else
|
||||
dotest=.dotest
|
||||
move_to_original_branch
|
||||
else
|
||||
die "No rebase in progress?"
|
||||
fi
|
||||
git reset --hard $(cat "$dotest/orig-head")
|
||||
rm -r "$dotest"
|
||||
|
||||
@@ -2577,8 +2577,8 @@ sub rebuild {
|
||||
my ($log, $ctx) =
|
||||
command_output_pipe(qw/rev-list --pretty=raw --no-color --reverse/,
|
||||
$self->refname, '--');
|
||||
my $full_url = $self->full_url;
|
||||
remove_username($full_url);
|
||||
my $metadata_url = $self->metadata_url;
|
||||
remove_username($metadata_url);
|
||||
my $svn_uuid = $self->ra_uuid;
|
||||
my $c;
|
||||
while (<$log>) {
|
||||
@@ -2596,7 +2596,7 @@ sub rebuild {
|
||||
# if we merged or otherwise started elsewhere, this is
|
||||
# how we break out of it
|
||||
if (($uuid ne $svn_uuid) ||
|
||||
($full_url && $url && ($url ne $full_url))) {
|
||||
($metadata_url && $url && ($url ne $metadata_url))) {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
@@ -344,7 +344,10 @@ void usage_with_options_internal(const char * const *usagestr,
|
||||
break;
|
||||
case OPTION_INTEGER:
|
||||
if (opts->flags & PARSE_OPT_OPTARG)
|
||||
pos += fprintf(stderr, "[<n>]");
|
||||
if (opts->long_name)
|
||||
pos += fprintf(stderr, "[=<n>]");
|
||||
else
|
||||
pos += fprintf(stderr, "[<n>]");
|
||||
else
|
||||
pos += fprintf(stderr, " <n>");
|
||||
break;
|
||||
@@ -355,12 +358,18 @@ void usage_with_options_internal(const char * const *usagestr,
|
||||
case OPTION_STRING:
|
||||
if (opts->argh) {
|
||||
if (opts->flags & PARSE_OPT_OPTARG)
|
||||
pos += fprintf(stderr, " [<%s>]", opts->argh);
|
||||
if (opts->long_name)
|
||||
pos += fprintf(stderr, "[=<%s>]", opts->argh);
|
||||
else
|
||||
pos += fprintf(stderr, "[<%s>]", opts->argh);
|
||||
else
|
||||
pos += fprintf(stderr, " <%s>", opts->argh);
|
||||
} else {
|
||||
if (opts->flags & PARSE_OPT_OPTARG)
|
||||
pos += fprintf(stderr, " [...]");
|
||||
if (opts->long_name)
|
||||
pos += fprintf(stderr, "[=...]");
|
||||
else
|
||||
pos += fprintf(stderr, "[...]");
|
||||
else
|
||||
pos += fprintf(stderr, " ...");
|
||||
}
|
||||
|
||||
17
path.c
17
path.c
@@ -330,6 +330,23 @@ const char *make_nonrelative_path(const char *path)
|
||||
/* We allow "recursive" symbolic links. Only within reason, though. */
|
||||
#define MAXDEPTH 5
|
||||
|
||||
const char *make_relative_path(const char *abs, const char *base)
|
||||
{
|
||||
static char buf[PATH_MAX + 1];
|
||||
int baselen;
|
||||
if (!base)
|
||||
return abs;
|
||||
baselen = strlen(base);
|
||||
if (prefixcmp(abs, base))
|
||||
return abs;
|
||||
if (abs[baselen] == '/')
|
||||
baselen++;
|
||||
else if (base[baselen - 1] != '/')
|
||||
return abs;
|
||||
strcpy(buf, abs + baselen);
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *make_absolute_path(const char *path)
|
||||
{
|
||||
static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1];
|
||||
|
||||
3
setup.c
3
setup.c
@@ -308,9 +308,10 @@ void setup_work_tree(void)
|
||||
work_tree = get_git_work_tree();
|
||||
git_dir = get_git_dir();
|
||||
if (!is_absolute_path(git_dir))
|
||||
set_git_dir(make_absolute_path(git_dir));
|
||||
git_dir = make_absolute_path(git_dir);
|
||||
if (!work_tree || chdir(work_tree))
|
||||
die("This operation must be run in a work tree");
|
||||
set_git_dir(make_relative_path(git_dir, work_tree));
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
|
||||
10
sha1_file.c
10
sha1_file.c
@@ -120,6 +120,15 @@ int safe_create_leading_directories(char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int safe_create_leading_directories_const(const char *path)
|
||||
{
|
||||
/* path points to cache entries, so xstrdup before messing with it */
|
||||
char *buf = xstrdup(path);
|
||||
int result = safe_create_leading_directories(buf);
|
||||
free(buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *sha1_to_hex(const unsigned char *sha1)
|
||||
{
|
||||
static int bufno;
|
||||
@@ -2122,6 +2131,7 @@ static int create_tmpfile(char *buffer, size_t bufsiz, const char *filename)
|
||||
fd = mkstemp(buffer);
|
||||
if (fd < 0 && dirlen) {
|
||||
/* Make sure the directory exists */
|
||||
memcpy(buffer, filename, dirlen);
|
||||
buffer[dirlen-1] = 0;
|
||||
if (mkdir(buffer, 0777) || adjust_shared_perm(buffer))
|
||||
return -1;
|
||||
|
||||
@@ -11,23 +11,35 @@ cat > expect.err << EOF
|
||||
usage: test-parse-options <options>
|
||||
|
||||
-b, --boolean get a boolean
|
||||
-4, --or4 bitwise-or boolean with ...0100
|
||||
|
||||
-i, --integer <n> get a integer
|
||||
-j <n> get a integer, too
|
||||
--set23 set integer to 23
|
||||
-t <time> get timestamp of <time>
|
||||
-L, --length <str> get length of <str>
|
||||
|
||||
string options
|
||||
String options
|
||||
-s, --string <string>
|
||||
get a string
|
||||
--string2 <str> get another string
|
||||
--st <st> get another string (pervert ordering)
|
||||
-o <str> get another string
|
||||
--default-string set string to default
|
||||
|
||||
magic arguments
|
||||
Magic arguments
|
||||
--quux means --quux
|
||||
|
||||
Standard options
|
||||
--abbrev[=<n>] use <n> digits to display SHA-1s
|
||||
-v, --verbose be verbose
|
||||
-n, --dry-run dry run
|
||||
-q, --quiet be quiet
|
||||
|
||||
EOF
|
||||
|
||||
test_expect_success 'test help' '
|
||||
! test-parse-options -h > output 2> output.err &&
|
||||
test_must_fail test-parse-options -h > output 2> output.err &&
|
||||
test ! -s output &&
|
||||
test_cmp expect.err output.err
|
||||
'
|
||||
@@ -36,21 +48,31 @@ cat > expect << EOF
|
||||
boolean: 2
|
||||
integer: 1729
|
||||
string: 123
|
||||
abbrev: 7
|
||||
verbose: 2
|
||||
quiet: no
|
||||
dry run: yes
|
||||
EOF
|
||||
|
||||
test_expect_success 'short options' '
|
||||
test-parse-options -s123 -b -i 1729 -b > output 2> output.err &&
|
||||
test-parse-options -s123 -b -i 1729 -b -vv -n > output 2> output.err &&
|
||||
test_cmp expect output &&
|
||||
test ! -s output.err
|
||||
'
|
||||
|
||||
cat > expect << EOF
|
||||
boolean: 2
|
||||
integer: 1729
|
||||
string: 321
|
||||
abbrev: 10
|
||||
verbose: 2
|
||||
quiet: no
|
||||
dry run: no
|
||||
EOF
|
||||
|
||||
test_expect_success 'long options' '
|
||||
test-parse-options --boolean --integer 1729 --boolean --string2=321 \
|
||||
--verbose --verbose --no-dry-run --abbrev=10 \
|
||||
> output 2> output.err &&
|
||||
test ! -s output.err &&
|
||||
test_cmp expect output
|
||||
@@ -60,6 +82,10 @@ cat > expect << EOF
|
||||
boolean: 1
|
||||
integer: 13
|
||||
string: 123
|
||||
abbrev: 7
|
||||
verbose: 0
|
||||
quiet: no
|
||||
dry run: no
|
||||
arg 00: a1
|
||||
arg 01: b1
|
||||
arg 02: --boolean
|
||||
@@ -76,6 +102,10 @@ cat > expect << EOF
|
||||
boolean: 0
|
||||
integer: 2
|
||||
string: (not set)
|
||||
abbrev: 7
|
||||
verbose: 0
|
||||
quiet: no
|
||||
dry run: no
|
||||
EOF
|
||||
|
||||
test_expect_success 'unambiguously abbreviated option' '
|
||||
@@ -99,6 +129,10 @@ cat > expect << EOF
|
||||
boolean: 0
|
||||
integer: 0
|
||||
string: 123
|
||||
abbrev: 7
|
||||
verbose: 0
|
||||
quiet: no
|
||||
dry run: no
|
||||
EOF
|
||||
|
||||
test_expect_success 'non ambiguous option (after two options it abbreviates)' '
|
||||
@@ -107,20 +141,24 @@ test_expect_success 'non ambiguous option (after two options it abbreviates)' '
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
cat > expect.err << EOF
|
||||
cat > typo.err << EOF
|
||||
error: did you mean \`--boolean\` (with two dashes ?)
|
||||
EOF
|
||||
|
||||
test_expect_success 'detect possible typos' '
|
||||
! test-parse-options -boolean > output 2> output.err &&
|
||||
test_must_fail test-parse-options -boolean > output 2> output.err &&
|
||||
test ! -s output &&
|
||||
test_cmp expect.err output.err
|
||||
test_cmp typo.err output.err
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
boolean: 0
|
||||
integer: 0
|
||||
string: (not set)
|
||||
abbrev: 7
|
||||
verbose: 0
|
||||
quiet: no
|
||||
dry run: no
|
||||
arg 00: --quux
|
||||
EOF
|
||||
|
||||
@@ -130,4 +168,68 @@ test_expect_success 'keep some options as arguments' '
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
boolean: 0
|
||||
integer: 1
|
||||
string: default
|
||||
abbrev: 7
|
||||
verbose: 0
|
||||
quiet: yes
|
||||
dry run: no
|
||||
arg 00: foo
|
||||
EOF
|
||||
|
||||
test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' '
|
||||
test-parse-options -t "1970-01-01 00:00:01 +0000" --default-string \
|
||||
foo -q > output 2> output.err &&
|
||||
test ! -s output.err &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
Callback: "four", 0
|
||||
boolean: 5
|
||||
integer: 4
|
||||
string: (not set)
|
||||
abbrev: 7
|
||||
verbose: 0
|
||||
quiet: no
|
||||
dry run: no
|
||||
EOF
|
||||
|
||||
test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' '
|
||||
test-parse-options --length=four -b -4 > output 2> output.err &&
|
||||
test ! -s output.err &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
Callback: "not set", 1
|
||||
EOF
|
||||
|
||||
test_expect_success 'OPT_CALLBACK() and callback errors work' '
|
||||
test_must_fail test-parse-options --no-length > output 2> output.err &&
|
||||
test_cmp expect output &&
|
||||
test_cmp expect.err output.err
|
||||
'
|
||||
|
||||
cat > expect <<EOF
|
||||
boolean: 1
|
||||
integer: 23
|
||||
string: (not set)
|
||||
abbrev: 7
|
||||
verbose: 0
|
||||
quiet: no
|
||||
dry run: no
|
||||
EOF
|
||||
|
||||
test_expect_success 'OPT_BIT() and OPT_SET_INT() work' '
|
||||
test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err &&
|
||||
test ! -s output.err &&
|
||||
test_cmp expect output
|
||||
'
|
||||
|
||||
# --or4
|
||||
# --no-or4
|
||||
|
||||
test_done
|
||||
|
||||
@@ -13,7 +13,7 @@ usage: some-command [options] <args>...
|
||||
--bar ... some cool option --bar with an argument
|
||||
|
||||
An option group Header
|
||||
-C [...] option C with an optional argument
|
||||
-C[...] option C with an optional argument
|
||||
|
||||
Extras
|
||||
--extra1 line above used to cause a segfault but no longer does
|
||||
|
||||
@@ -30,4 +30,26 @@ test_expect_success 'clone checks out files' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'clone respects GIT_WORK_TREE' '
|
||||
|
||||
GIT_WORK_TREE=worktree git clone src bare &&
|
||||
test -f bare/config &&
|
||||
test -f worktree/file
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'clone creates intermediate directories' '
|
||||
|
||||
git clone src long/path/to/dst &&
|
||||
test -f long/path/to/dst/file
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'clone creates intermediate directories for bare repo' '
|
||||
|
||||
git clone --bare src long/path/to/bare/dst &&
|
||||
test -f long/path/to/bare/dst/config
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -212,7 +212,11 @@ test_expect_success 'do not fire editor in the presence of conflicts' '
|
||||
# Must fail due to conflict
|
||||
test_must_fail git cherry-pick -n master &&
|
||||
echo "editor not started" >.git/result &&
|
||||
test_must_fail GIT_EDITOR="$(pwd)/.git/FAKE_EDITOR" git commit &&
|
||||
(
|
||||
GIT_EDITOR="$(pwd)/.git/FAKE_EDITOR" &&
|
||||
export GIT_EDITOR &&
|
||||
test_must_fail git commit
|
||||
) &&
|
||||
test "$(cat .git/result)" = "editor not started"
|
||||
'
|
||||
|
||||
|
||||
32
t/t9123-git-svn-rebuild-with-rewriteroot.sh
Executable file
32
t/t9123-git-svn-rebuild-with-rewriteroot.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2008 Jan Krüger
|
||||
#
|
||||
|
||||
test_description='git-svn respects rewriteRoot during rebuild'
|
||||
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
mkdir import
|
||||
cd import
|
||||
touch foo
|
||||
svn import -m 'import for git-svn' . "$svnrepo" >/dev/null
|
||||
cd ..
|
||||
rm -rf import
|
||||
|
||||
test_expect_success 'init, fetch and checkout repository' '
|
||||
git svn init --rewrite-root=http://invalid.invalid/ "$svnrepo" &&
|
||||
git svn fetch
|
||||
git checkout -b mybranch remotes/git-svn
|
||||
'
|
||||
|
||||
test_expect_success 'remove rev_map' '
|
||||
rm "$GIT_SVN_DIR"/.rev_map.*
|
||||
'
|
||||
|
||||
test_expect_success 'rebuild rev_map' '
|
||||
git svn rebase >/dev/null
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -2,9 +2,22 @@
|
||||
#include "parse-options.h"
|
||||
|
||||
static int boolean = 0;
|
||||
static int integer = 0;
|
||||
static unsigned long integer = 0;
|
||||
static int abbrev = 7;
|
||||
static int verbose = 0, dry_run = 0, quiet = 0;
|
||||
static char *string = NULL;
|
||||
|
||||
int length_callback(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
printf("Callback: \"%s\", %d\n",
|
||||
(arg ? arg : "not set"), unset);
|
||||
if (unset)
|
||||
return 1; /* do not support unset */
|
||||
|
||||
*(unsigned long *)opt->value = strlen(arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
const char *usage[] = {
|
||||
@@ -13,15 +26,29 @@ int main(int argc, const char **argv)
|
||||
};
|
||||
struct option options[] = {
|
||||
OPT_BOOLEAN('b', "boolean", &boolean, "get a boolean"),
|
||||
OPT_BIT('4', "or4", &boolean,
|
||||
"bitwise-or boolean with ...0100", 4),
|
||||
OPT_GROUP(""),
|
||||
OPT_INTEGER('i', "integer", &integer, "get a integer"),
|
||||
OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
|
||||
OPT_GROUP("string options"),
|
||||
OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
|
||||
OPT_DATE('t', NULL, &integer, "get timestamp of <time>"),
|
||||
OPT_CALLBACK('L', "length", &integer, "str",
|
||||
"get length of <str>", length_callback),
|
||||
OPT_GROUP("String options"),
|
||||
OPT_STRING('s', "string", &string, "string", "get a string"),
|
||||
OPT_STRING(0, "string2", &string, "str", "get another string"),
|
||||
OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
|
||||
OPT_STRING('o', NULL, &string, "str", "get another string"),
|
||||
OPT_GROUP("magic arguments"),
|
||||
OPT_SET_PTR(0, "default-string", &string,
|
||||
"set string to default", (unsigned long)"default"),
|
||||
OPT_GROUP("Magic arguments"),
|
||||
OPT_ARGUMENT("quux", "means --quux"),
|
||||
OPT_GROUP("Standard options"),
|
||||
OPT__ABBREV(&abbrev),
|
||||
OPT__VERBOSE(&verbose),
|
||||
OPT__DRY_RUN(&dry_run),
|
||||
OPT__QUIET(&quiet),
|
||||
OPT_END(),
|
||||
};
|
||||
int i;
|
||||
@@ -29,8 +56,12 @@ int main(int argc, const char **argv)
|
||||
argc = parse_options(argc, argv, options, usage, 0);
|
||||
|
||||
printf("boolean: %d\n", boolean);
|
||||
printf("integer: %d\n", integer);
|
||||
printf("integer: %lu\n", integer);
|
||||
printf("string: %s\n", string ? string : "(not set)");
|
||||
printf("abbrev: %d\n", abbrev);
|
||||
printf("verbose: %d\n", verbose);
|
||||
printf("quiet: %s\n", quiet ? "yes" : "no");
|
||||
printf("dry run: %s\n", dry_run ? "yes" : "no");
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
printf("arg %02d: %s\n", i, argv[i]);
|
||||
|
||||
Reference in New Issue
Block a user