From: Junio C Hamano Date: Thu, 3 Apr 2014 19:38:04 +0000 (-0700) Subject: Merge branch 'ep/shell-command-substitution' X-Git-Tag: v2.0.0-rc0~30 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/2b06c1e57eecde25ff762cc12939d8a6d8f143cc?hp=75ee3d7078fbcc3b87a3ae5e0cf42f46256c5da4 Merge branch 'ep/shell-command-substitution' * ep/shell-command-substitution: git-am.sh: use the $(...) construct for command substitution check-builtins.sh: use the $(...) construct for command substitution --- diff --git a/Documentation/RelNotes/2.0.0.txt b/Documentation/RelNotes/2.0.0.txt index 50bbc28e21..9c1238c385 100644 --- a/Documentation/RelNotes/2.0.0.txt +++ b/Documentation/RelNotes/2.0.0.txt @@ -47,6 +47,17 @@ Updates since v1.9 series UI, Workflows & Features + * The "rev-parse --parseopt" mechanism used by scripted Porcelains to + parse command line options and to give help text learned to take + the argv-help (the placeholder string for an option parameter, + e.g. "key-id" in "--gpg-sign="). + + * The pattern to find where the function begins in C/C++ used in + "diff" and "grep -p" have been updated to help C++ source better. + + * "git rebase" learned to interpret a lone "-" as "@{-1}", the + branch that we were previously on. + * "git commit --cleanup=" learned a new mode, scissors. * "git tag --list" output can be sorted using "version sort" with @@ -115,11 +126,6 @@ UI, Workflows & Features fully for paths the index knows about but the tree-ish the command resets to does not (these paths are kept as intend-to-add entries). - * Newly cloned submodule repositories by "git submodule update", - when the "checkout" update mode is used, will be on a local - branch instead of on a detached HEAD, just like submodules added - with "git submodule add". - Performance, Internal Implementation, etc. @@ -155,6 +161,35 @@ Unless otherwise noted, all the fixes since v1.9 in the maintenance track are contained in this release (see the maintenance releases' notes for details). + * "git status --porcelain --branch" showed its output with labels + "ahead/behind/gone" translated to the user's locale. + (merge 7a76c28 mm/status-porcelain-format-i18n-fix later to maint). + + + * "git repack" died when asked to (re)pack with the reachability + bitmap when a bitmap cannot be built; instead, just (re)pack + without producing a bitmap in such a case, with a warning. + (merge 373c67d jk/pack-bitmap later to maint). + + + * The progress output while repacking and transferring objects showed + an apparent large silence while writing the objects out of existing + packfiles, when the reachability bitmap was in use. + (merge 78d2214 jk/pack-bitmap-progress later to maint). + + + * A stray environment variable $prefix could have leaked into and + affected the behaviour of the "subtree" script (in contrib/). + + + * When it is not necessary to edit a commit log message (e.g. "git + commit -m" is given a message without specifying "-e"), we used to + disable the spawning of the editor by overriding GIT_EDITOR, but + this means all the uses of the editor, other than to edit the + commit log message, are also affected. + (merge b549be0 bp/commit-p-editor later to maint). + + * "git mv" that moves a submodule forgot to adjust the array that uses to keep track of which submodules were to be moved to update its configuration. diff --git a/Documentation/config.txt b/Documentation/config.txt index 73c8973aae..c415aadbbc 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -131,8 +131,13 @@ Variables Note that this list is non-comprehensive and not necessarily complete. For command-specific variables, you will find a more detailed description -in the appropriate manual page. You will find a description of non-core -porcelain configuration variables in the respective porcelain documentation. +in the appropriate manual page. + +Other git-related tools may and do use their own variables. When +inventing new variables for use in your own tool, make sure their +names do not conflict with those that are used by Git itself and +other popular tools, and describe them in your documentation. + advice.*:: These variables control various optional help messages designed to diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 0d2cdcde55..e05e6b3593 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -284,13 +284,13 @@ 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. +(should be one or more) are used for the usage. The lines after the separator describe the options. Each line of options has this format: ------------ -* SP+ help LF +*? SP+ help LF ------------ ``:: @@ -313,6 +313,12 @@ Each line of options has this format: * Use `!` to not make the corresponding negated long option available. +``:: + ``, if specified, is used as a name of the argument in the + help output, for options that take arguments. `` is + terminated by the first whitespace. When you need to use space in the + argument hint use dash instead. + The remainder of the line, after stripping the spaces, is used as the help associated to the option. @@ -333,6 +339,8 @@ h,help show the help foo some nifty option --foo bar= some cool option --bar with an argument +baz=arg another cool option --baz with a named argument +qux?path qux may take a path argument but has meaning by itself An option group Header C? option C with an optional argument" @@ -340,6 +348,28 @@ C? option C with an optional argument" eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)" ------------ + +Usage text +~~~~~~~~~~ + +When `"$@"` is `-h` or `--help` in the above example, the following +usage text would be shown: + +------------ +usage: some-command [options] ... + + some-command does foo and bar! + + -h, --help show the help + --foo some nifty option --foo + --bar ... some cool option --bar with an argument + --bar another cool option --baz with a named argument + --qux[=] qux may take a path argument but has meaning by itself + +An option group Header + -C[...] option C with an optional argument +------------ + SQ-QUOTE -------- diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index a4acaa038c..def635f578 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -97,7 +97,7 @@ configuration variable documented in linkgit:git-config[1]. OUTPUT ------ The output from this command is designed to be used as a commit -template comment, and all the output lines are prefixed with '#'. +template comment. The default, long format, is designed to be human readable, verbose and descriptive. Its contents and format are subject to change at any time. diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 46c1eebb93..89c4d3e394 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -15,7 +15,7 @@ SYNOPSIS 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] deinit [-f|--force] [--] ... 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] - [-f|--force] [--checkout|--rebase|--merge] [--reference ] + [-f|--force] [--rebase|--merge] [--reference ] [--depth ] [--recursive] [--] [...] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) ] [commit] [--] [...] @@ -155,31 +155,13 @@ it contains local modifications. update:: Update the registered submodules, i.e. clone missing submodules and - checkout the commit specified in the index of the containing - repository. The update mode defaults to `checkout`, but can be - configured with the `submodule..update` setting or the - `--rebase`, `--merge`, or `--checkout` options. -+ -For updates that clone missing submodules, checkout-mode updates will -create submodules with detached HEADs; all other modes will create -submodules with a local branch named after `submodule..branch`. -+ -For updates that do not clone missing submodules, the submodule's HEAD -is only touched when the remote reference does not match the -submodule's HEAD (for none-mode updates, the submodule is never -touched). The remote reference is usually the gitlinked commit from -the superproject's tree, but with `--remote` it is the upstream -subproject's `submodule..branch`. This remote reference is -integrated with the submodule's HEAD using the specified update mode. -For checkout-mode updates, that will result in a detached HEAD. For -rebase- and merge-mode updates, the commit referenced by the -submodule's HEAD may change, but the symbolic reference will remain -unchanged (i.e. checked-out branches will still be checked-out -branches, and detached HEADs will still be detached HEADs). If none -of the builtin modes fit your needs, set `submodule..update` to -`!command` to configure a custom integration command. `command` can -be any arbitrary shell command that takes a single argument, namely -the sha1 to update to. + checkout the commit specified in the index of the containing repository. + This will make the submodules HEAD be detached unless `--rebase` or + `--merge` is specified or the key `submodule.$name.update` is set to + `rebase`, `merge` or `none`. `none` can be overridden by specifying + `--checkout`. Setting the key `submodule.$name.update` to `!command` + will cause `command` to be run. `command` can be any arbitrary shell + command that takes a single argument, namely the sha1 to update to. + If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the @@ -247,7 +229,7 @@ OPTIONS -b:: --branch:: Branch of repository to add as submodule. - The name of the branch is recorded as `submodule..branch` in + The name of the branch is recorded as `submodule..branch` in `.gitmodules` for `update --remote`. -f:: diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt index 1e9e38ae40..7e03fcc62d 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.txt @@ -166,8 +166,14 @@ gitk --max-count=100 --all \-- Makefile:: Files ----- -Gitk creates the .gitk file in your $HOME directory to store preferences -such as display options, font, and colors. +User configuration and preferences are stored at: + +* '$XDG_CONFIG_HOME/git/gitk' if it exists, otherwise +* '$HOME/.gitk' if it exists + +If neither of the above exist then '$XDG_CONFIG_HOME/git/gitk' is created and +used by default. If '$XDG_CONFIG_HOME' is not set it defaults to +'$HOME/.config' in all cases. History ------- diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index f539e3f66a..347a9f76ee 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -55,10 +55,6 @@ submodule..branch:: A remote branch name for tracking updates in the upstream submodule. If the option is not specified, it defaults to 'master'. See the `--remote` documentation in linkgit:git-submodule[1] for details. -+ -This branch name is also used for the local branch created by -non-checkout cloning updates. See the `update` documentation in -linkgit:git-submodule[1] for details. submodule..fetchRecurseSubmodules:: This option can be used to control recursive fetching of this diff --git a/Makefile b/Makefile index 36463919af..c5316a34ac 100644 --- a/Makefile +++ b/Makefile @@ -59,9 +59,9 @@ all:: # FreeBSD can use either, but MinGW and some others need to use # libcharset.h's locale_charset() instead. # -# Define CHARSET_LIB to you need to link with library other than -liconv to +# Define CHARSET_LIB to the library you need to link with in order to # use locale_charset() function. On some platforms this needs to set to -# -lcharset +# -lcharset, on others to -liconv . # # Define LIBC_CONTAINS_LIBINTL if your gettext implementation doesn't # need -lintl when linking. diff --git a/branch.c b/branch.c index 8eecb1d8c0..660097bc29 100644 --- a/branch.c +++ b/branch.c @@ -77,29 +77,29 @@ void install_branch_config(int flag, const char *local, const char *origin, cons strbuf_release(&key); if (flag & BRANCH_CONFIG_VERBOSE) { - if (shortname && origin) - printf_ln(rebasing ? - _("Branch %s set up to track remote branch %s from %s by rebasing.") : - _("Branch %s set up to track remote branch %s from %s."), - local, shortname, origin); - else if (shortname && !origin) - printf_ln(rebasing ? - _("Branch %s set up to track local branch %s by rebasing.") : - _("Branch %s set up to track local branch %s."), - local, shortname); - else if (!shortname && origin) - printf_ln(rebasing ? - _("Branch %s set up to track remote ref %s by rebasing.") : - _("Branch %s set up to track remote ref %s."), - local, remote); - else if (!shortname && !origin) - printf_ln(rebasing ? - _("Branch %s set up to track local ref %s by rebasing.") : - _("Branch %s set up to track local ref %s."), - local, remote); - else - die("BUG: impossible combination of %p and %p", - shortname, origin); + if (shortname) { + if (origin) + printf_ln(rebasing ? + _("Branch %s set up to track remote branch %s from %s by rebasing.") : + _("Branch %s set up to track remote branch %s from %s."), + local, shortname, origin); + else + printf_ln(rebasing ? + _("Branch %s set up to track local branch %s by rebasing.") : + _("Branch %s set up to track local branch %s."), + local, shortname); + } else { + if (origin) + printf_ln(rebasing ? + _("Branch %s set up to track remote ref %s by rebasing.") : + _("Branch %s set up to track remote ref %s."), + local, remote); + else + printf_ln(rebasing ? + _("Branch %s set up to track local ref %s by rebasing.") : + _("Branch %s set up to track local ref %s."), + local, remote); + } } } diff --git a/builtin/add.c b/builtin/add.c index 4b045bace1..459208a326 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -15,6 +15,7 @@ #include "diffcore.h" #include "revision.h" #include "bulk-checkin.h" +#include "argv-array.h" static const char * const builtin_add_usage[] = { N_("git add [options] [--] ..."), @@ -141,23 +142,21 @@ static void refresh(int verbose, const struct pathspec *pathspec) int run_add_interactive(const char *revision, const char *patch_mode, const struct pathspec *pathspec) { - int status, ac, i; - const char **args; + int status, i; + struct argv_array argv = ARGV_ARRAY_INIT; - args = xcalloc(sizeof(const char *), (pathspec->nr + 6)); - ac = 0; - args[ac++] = "add--interactive"; + argv_array_push(&argv, "add--interactive"); if (patch_mode) - args[ac++] = patch_mode; + argv_array_push(&argv, patch_mode); if (revision) - args[ac++] = revision; - args[ac++] = "--"; + argv_array_push(&argv, revision); + argv_array_push(&argv, "--"); for (i = 0; i < pathspec->nr; i++) /* pass original pathspec, to be re-parsed */ - args[ac++] = pathspec->items[i].original; + argv_array_push(&argv, pathspec->items[i].original); - status = run_command_v_opt(args, RUN_GIT_CMD); - free(args); + status = run_command_v_opt(argv.argv, RUN_GIT_CMD); + argv_array_clear(&argv); return status; } diff --git a/builtin/checkout.c b/builtin/checkout.c index ada51fa70f..1b86d9c868 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -53,10 +53,10 @@ struct checkout_opts { static int post_checkout_hook(struct commit *old, struct commit *new, int changed) { - return run_hook(NULL, "post-checkout", - sha1_to_hex(old ? old->object.sha1 : null_sha1), - sha1_to_hex(new ? new->object.sha1 : null_sha1), - changed ? "1" : "0", NULL); + return run_hook_le(NULL, "post-checkout", + sha1_to_hex(old ? old->object.sha1 : null_sha1), + sha1_to_hex(new ? new->object.sha1 : null_sha1), + changed ? "1" : "0", NULL); /* "new" can be NULL when checking out from the index before a commit exists. */ diff --git a/builtin/clone.c b/builtin/clone.c index 43e772ccdb..9b3c04d914 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -660,8 +660,8 @@ static int checkout(void) commit_locked_index(lock_file)) die(_("unable to write new index file")); - err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1), - sha1_to_hex(sha1), "1", NULL); + err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1), + sha1_to_hex(sha1), "1", NULL); if (!err && option_recursive) err = run_command_v_opt(argv_submodule, RUN_GIT_CMD); diff --git a/builtin/commit.c b/builtin/commit.c index 38f34e7cd3..d9550c54d0 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -611,7 +611,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, /* This checks and barfs if author is badly specified */ determine_author_info(author_ident); - if (!no_verify && run_hook(index_file, "pre-commit", NULL)) + if (!no_verify && run_commit_hook(use_editor, index_file, "pre-commit", NULL)) return 0; if (squash_message) { @@ -873,8 +873,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, return 0; } - if (run_hook(index_file, "prepare-commit-msg", - git_path(commit_editmsg), hook_arg1, hook_arg2, NULL)) + if (run_commit_hook(use_editor, index_file, "prepare-commit-msg", + git_path(commit_editmsg), hook_arg1, hook_arg2, NULL)) return 0; if (use_editor) { @@ -890,7 +890,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, } if (!no_verify && - run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) { + run_commit_hook(use_editor, index_file, "commit-msg", git_path(commit_editmsg), NULL)) { return 0; } @@ -1074,8 +1074,6 @@ static int parse_and_validate_options(int argc, const char *argv[], use_editor = 0; if (0 <= edit_flag) use_editor = edit_flag; - if (!use_editor) - setenv("GIT_EDITOR", ":", 1); /* Sanity check options */ if (amend && !current_head) @@ -1458,6 +1456,29 @@ static int run_rewrite_hook(const unsigned char *oldsha1, return finish_command(&proc); } +int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...) +{ + const char *hook_env[3] = { NULL }; + char index[PATH_MAX]; + va_list args; + int ret; + + snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); + hook_env[0] = index; + + /* + * Let the hook know that no editor will be launched. + */ + if (!editor_is_used) + hook_env[1] = "GIT_EDITOR=:"; + + va_start(args, name); + ret = run_hook_ve(hook_env, name, args); + va_end(args); + + return ret; +} + int cmd_commit(int argc, const char **argv, const char *prefix) { static struct wt_status s; @@ -1682,7 +1703,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) "not exceeded, and then \"git reset HEAD\" to recover.")); rerere(0); - run_hook(get_index_file(), "post-commit", NULL); + run_commit_hook(use_editor, get_index_file(), "post-commit", NULL); if (amend && !no_post_rewrite) { struct notes_rewrite_cfg *cfg; cfg = init_copy_notes_for_rewrite("amend"); diff --git a/builtin/gc.c b/builtin/gc.c index 63d400bcb2..11cf295515 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -184,7 +184,7 @@ static int need_to_gc(void) else if (!too_many_loose_objects()) return 0; - if (run_hook(NULL, "pre-auto-gc", NULL)) + if (run_hook_le(NULL, "pre-auto-gc", NULL)) return 0; return 1; } diff --git a/builtin/merge.c b/builtin/merge.c index f0cf1205fa..e15d0e145a 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -421,7 +421,7 @@ static void finish(struct commit *head_commit, } /* Run a post-merge hook */ - run_hook(NULL, "post-merge", squash ? "1" : "0", NULL); + run_hook_le(NULL, "post-merge", squash ? "1" : "0", NULL); strbuf_release(&reflog_message); } @@ -824,8 +824,8 @@ static void prepare_to_commit(struct commit_list *remoteheads) if (0 < option_edit) strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char); write_merge_msg(&msg); - if (run_hook(get_index_file(), "prepare-commit-msg", - git_path("MERGE_MSG"), "merge", NULL, NULL)) + if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg", + git_path("MERGE_MSG"), "merge", NULL)) abort_commit(remoteheads, NULL); if (0 < option_edit) { if (launch_editor(git_path("MERGE_MSG"), NULL, NULL)) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 0ee5f1ff94..7950c4342f 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -708,7 +708,7 @@ static struct object_entry **compute_write_order(void) static off_t write_reused_pack(struct sha1file *f) { unsigned char buffer[8192]; - off_t to_write; + off_t to_write, total; int fd; if (!is_pack_valid(reuse_packfile)) @@ -725,7 +725,7 @@ static off_t write_reused_pack(struct sha1file *f) if (reuse_packfile_offset < 0) reuse_packfile_offset = reuse_packfile->pack_size - 20; - to_write = reuse_packfile_offset - sizeof(struct pack_header); + total = to_write = reuse_packfile_offset - sizeof(struct pack_header); while (to_write) { int read_pack = xread(fd, buffer, sizeof(buffer)); @@ -738,10 +738,23 @@ static off_t write_reused_pack(struct sha1file *f) sha1write(f, buffer, read_pack); to_write -= read_pack; + + /* + * We don't know the actual number of objects written, + * only how many bytes written, how many bytes total, and + * how many objects total. So we can fake it by pretending all + * objects we are writing are the same size. This gives us a + * smooth progress meter, and at the end it matches the true + * answer. + */ + written = reuse_packfile_objects * + (((double)(total - to_write)) / total); + display_progress(progress_state, written); } close(fd); - written += reuse_packfile_objects; + written = reuse_packfile_objects; + display_progress(progress_state, written); return reuse_packfile_offset - sizeof(struct pack_header); } @@ -995,6 +1008,10 @@ static void create_object_entry(const unsigned char *sha1, entry->no_try_delta = no_try_delta; } +static const char no_closure_warning[] = N_( +"disabling bitmap writing, as some objects are not being packed" +); + static int add_object_entry(const unsigned char *sha1, enum object_type type, const char *name, int exclude) { @@ -1005,14 +1022,20 @@ static int add_object_entry(const unsigned char *sha1, enum object_type type, if (have_duplicate_entry(sha1, exclude, &index_pos)) return 0; - if (!want_object_in_pack(sha1, exclude, &found_pack, &found_offset)) + if (!want_object_in_pack(sha1, exclude, &found_pack, &found_offset)) { + /* The pack is missing an object, so it will not have closure */ + if (write_bitmap_index) { + warning(_(no_closure_warning)); + write_bitmap_index = 0; + } return 0; + } create_object_entry(sha1, type, pack_name_hash(name), exclude, name && no_try_delta(name), index_pos, found_pack, found_offset); - display_progress(progress_state, to_pack.nr_objects); + display_progress(progress_state, nr_result); return 1; } @@ -1028,7 +1051,7 @@ static int add_object_entry_from_bitmap(const unsigned char *sha1, create_object_entry(sha1, type, name_hash, 0, 0, index_pos, pack, offset); - display_progress(progress_state, to_pack.nr_objects); + display_progress(progress_state, nr_result); return 1; } @@ -2427,12 +2450,7 @@ static int get_object_list_from_bitmap(struct rev_info *revs) &reuse_packfile_offset)) { assert(reuse_packfile_objects); nr_result += reuse_packfile_objects; - - if (progress) { - fprintf(stderr, "Reusing existing pack: %d, done.\n", - reuse_packfile_objects); - fflush(stderr); - } + display_progress(progress_state, nr_result); } traverse_bitmap_commit_list(&add_object_entry_from_bitmap); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 45901df371..1a6122d3ae 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -395,9 +395,10 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) usage[unb++] = strbuf_detach(&sb, NULL); } - /* parse: (|,|)[=?]? SP+ */ + /* parse: (|,|)[*=?!]*? SP+ */ while (strbuf_getline(&sb, stdin, '\n') != EOF) { const char *s; + const char *end; struct option *o; if (!sb.len) @@ -419,6 +420,16 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) o->value = &parsed; o->flags = PARSE_OPT_NOARG; o->callback = &parseopt_dump; + + /* Possible argument name hint */ + end = s; + while (s > sb.buf && strchr("*=?!", s[-1]) == NULL) + --s; + if (s != sb.buf && s != end) + o->argh = xmemdupz(s, end - s); + if (s == sb.buf) + s = end; + while (s > sb.buf && strchr("*=?!", s[-1])) { switch (*--s) { case '=': diff --git a/commit.h b/commit.h index 55631f191f..a9f177ba48 100644 --- a/commit.h +++ b/commit.h @@ -304,4 +304,7 @@ extern void check_commit_signature(const struct commit* commit, struct signature int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused); +LAST_ARG_MUST_BE_NULL +extern int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...); + #endif /* COMMIT_H */ diff --git a/compat/vcbuild/scripts/clink.pl b/compat/vcbuild/scripts/clink.pl index 4374771df2..a87d0da512 100755 --- a/compat/vcbuild/scripts/clink.pl +++ b/compat/vcbuild/scripts/clink.pl @@ -33,6 +33,8 @@ push(@args, "libeay32.lib"); } elsif ("$arg" eq "-lssl") { push(@args, "ssleay32.lib"); + } elsif ("$arg" eq "-lcurl") { + push(@args, "libcurl.lib"); } elsif ("$arg" =~ /^-L/ && "$arg" ne "-LTCG") { $arg =~ s/^-L/-LIBPATH:/; push(@args, $arg); diff --git a/config.mak.uname b/config.mak.uname index 6069a44350..cfc2a9323f 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -340,7 +340,6 @@ ifeq ($(uname_S),Windows) UNRELIABLE_FSTAT = UnfortunatelyYes OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo NO_REGEX = YesPlease - NO_CURL = YesPlease NO_GETTEXT = YesPlease NO_PYTHON = YesPlease BLK_SHA1 = YesPlease diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg index eb89ef6779..36b526106b 100755 --- a/contrib/remote-helpers/git-remote-hg +++ b/contrib/remote-helpers/git-remote-hg @@ -643,7 +643,10 @@ def do_list(parser): print "? refs/heads/branches/%s" % gitref(branch) for bmark in bmarks: - print "? refs/heads/%s" % gitref(bmark) + if bmarks[bmark].hex() == '0000000000000000000000000000000000000000': + warn("Ignoring invalid bookmark '%s'", bmark) + else: + print "? refs/heads/%s" % gitref(bmark) for tag, node in repo.tagslist(): if tag == 'tip': diff --git a/contrib/remote-helpers/test-hg.sh b/contrib/remote-helpers/test-hg.sh index a933b1e30c..7d90056cf3 100755 --- a/contrib/remote-helpers/test-hg.sh +++ b/contrib/remote-helpers/test-hg.sh @@ -772,4 +772,77 @@ test_expect_success 'remote double failed push' ' ) ' +test_expect_success 'clone remote with master null bookmark, then push to the bookmark' ' + test_when_finished "rm -rf gitrepo* hgrepo*" && + + hg init hgrepo && + ( + cd hgrepo && + echo a >a && + hg add a && + hg commit -m a && + hg bookmark -r null master + ) && + + git clone "hg::hgrepo" gitrepo && + check gitrepo HEAD a && + ( + cd gitrepo && + git checkout --quiet -b master && + echo b >b && + git add b && + git commit -m b && + git push origin master + ) +' + +test_expect_success 'clone remote with default null bookmark, then push to the bookmark' ' + test_when_finished "rm -rf gitrepo* hgrepo*" && + + hg init hgrepo && + ( + cd hgrepo && + echo a >a && + hg add a && + hg commit -m a && + hg bookmark -r null -f default + ) && + + git clone "hg::hgrepo" gitrepo && + check gitrepo HEAD a && + ( + cd gitrepo && + git checkout --quiet -b default && + echo b >b && + git add b && + git commit -m b && + git push origin default + ) +' + +test_expect_success 'clone remote with generic null bookmark, then push to the bookmark' ' + test_when_finished "rm -rf gitrepo* hgrepo*" && + + hg init hgrepo && + ( + cd hgrepo && + echo a >a && + hg add a && + hg commit -m a && + hg bookmark -r null bmark + ) && + + git clone "hg::hgrepo" gitrepo && + check gitrepo HEAD a && + ( + cd gitrepo && + git checkout --quiet -b bmark && + git remote -v && + echo b >b && + git add b && + git commit -m b && + git push origin bmark + ) +' + test_done diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index dc59a91031..db925ca769 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -46,6 +46,7 @@ ignore_joins= annotate= squash= message= +prefix= debug() { diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c index 401eb72c61..185f86b284 100644 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@ -12,47 +12,6 @@ typedef int (*pickaxe_fn)(mmfile_t *one, mmfile_t *two, struct diff_options *o, regex_t *regexp, kwset_t kws); -static int pickaxe_match(struct diff_filepair *p, struct diff_options *o, - regex_t *regexp, kwset_t kws, pickaxe_fn fn); - -static void pickaxe(struct diff_queue_struct *q, struct diff_options *o, - regex_t *regexp, kwset_t kws, pickaxe_fn fn) -{ - int i; - struct diff_queue_struct outq; - - DIFF_QUEUE_CLEAR(&outq); - - if (o->pickaxe_opts & DIFF_PICKAXE_ALL) { - /* Showing the whole changeset if needle exists */ - for (i = 0; i < q->nr; i++) { - struct diff_filepair *p = q->queue[i]; - if (pickaxe_match(p, o, regexp, kws, fn)) - return; /* do not munge the queue */ - } - - /* - * Otherwise we will clear the whole queue by copying - * the empty outq at the end of this function, but - * first clear the current entries in the queue. - */ - for (i = 0; i < q->nr; i++) - diff_free_filepair(q->queue[i]); - } else { - /* Showing only the filepairs that has the needle */ - for (i = 0; i < q->nr; i++) { - struct diff_filepair *p = q->queue[i]; - if (pickaxe_match(p, o, regexp, kws, fn)) - diff_q(&outq, p); - else - diff_free_filepair(p); - } - } - - free(q->queue); - *q = outq; -} - struct diffgrep_cb { regex_t *regexp; int hit; @@ -108,29 +67,6 @@ static int diff_grep(mmfile_t *one, mmfile_t *two, return ecbdata.hit; } -static void diffcore_pickaxe_grep(struct diff_options *o) -{ - int err; - regex_t regex; - int cflags = REG_EXTENDED | REG_NEWLINE; - - if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE)) - cflags |= REG_ICASE; - - err = regcomp(®ex, o->pickaxe, cflags); - if (err) { - char errbuf[1024]; - regerror(err, ®ex, errbuf, 1024); - regfree(®ex); - die("invalid regex: %s", errbuf); - } - - pickaxe(&diff_queued_diff, o, ®ex, NULL, diff_grep); - - regfree(®ex); - return; -} - static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws) { unsigned int cnt; @@ -158,13 +94,10 @@ static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws) while (sz) { struct kwsmatch kwsm; size_t offset = kwsexec(kws, data, sz, &kwsm); - const char *found; if (offset == -1) break; - else - found = data + offset; - sz -= found - data + kwsm.size[0]; - data = found + kwsm.size[0]; + sz -= offset + kwsm.size[0]; + data += offset + kwsm.size[0]; cnt++; } } @@ -227,17 +160,57 @@ static int pickaxe_match(struct diff_filepair *p, struct diff_options *o, return ret; } -static void diffcore_pickaxe_count(struct diff_options *o) +static void pickaxe(struct diff_queue_struct *q, struct diff_options *o, + regex_t *regexp, kwset_t kws, pickaxe_fn fn) +{ + int i; + struct diff_queue_struct outq; + + DIFF_QUEUE_CLEAR(&outq); + + if (o->pickaxe_opts & DIFF_PICKAXE_ALL) { + /* Showing the whole changeset if needle exists */ + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + if (pickaxe_match(p, o, regexp, kws, fn)) + return; /* do not munge the queue */ + } + + /* + * Otherwise we will clear the whole queue by copying + * the empty outq at the end of this function, but + * first clear the current entries in the queue. + */ + for (i = 0; i < q->nr; i++) + diff_free_filepair(q->queue[i]); + } else { + /* Showing only the filepairs that has the needle */ + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + if (pickaxe_match(p, o, regexp, kws, fn)) + diff_q(&outq, p); + else + diff_free_filepair(p); + } + } + + free(q->queue); + *q = outq; +} + +void diffcore_pickaxe(struct diff_options *o) { const char *needle = o->pickaxe; int opts = o->pickaxe_opts; - unsigned long len = strlen(needle); regex_t regex, *regexp = NULL; kwset_t kws = NULL; - if (opts & DIFF_PICKAXE_REGEX) { + if (opts & (DIFF_PICKAXE_REGEX | DIFF_PICKAXE_KIND_G)) { int err; - err = regcomp(®ex, needle, REG_EXTENDED | REG_NEWLINE); + int cflags = REG_EXTENDED | REG_NEWLINE; + if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE)) + cflags |= REG_ICASE; + err = regcomp(®ex, needle, cflags); if (err) { /* The POSIX.2 people are surely sick */ char errbuf[1024]; @@ -249,24 +222,17 @@ static void diffcore_pickaxe_count(struct diff_options *o) } else { kws = kwsalloc(DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE) ? tolower_trans_tbl : NULL); - kwsincr(kws, needle, len); + kwsincr(kws, needle, strlen(needle)); kwsprep(kws); } - pickaxe(&diff_queued_diff, o, regexp, kws, has_changes); + /* Might want to warn when both S and G are on; I don't care... */ + pickaxe(&diff_queued_diff, o, regexp, kws, + (opts & DIFF_PICKAXE_KIND_G) ? diff_grep : has_changes); - if (opts & DIFF_PICKAXE_REGEX) - regfree(®ex); + if (regexp) + regfree(regexp); else kwsfree(kws); return; } - -void diffcore_pickaxe(struct diff_options *o) -{ - /* Might want to warn when both S and G are on; I don't care... */ - if (o->pickaxe_opts & DIFF_PICKAXE_KIND_G) - diffcore_pickaxe_grep(o); - else - diffcore_pickaxe_count(o); -} diff --git a/fsck.c b/fsck.c index 64bf279fd7..abed62bac7 100644 --- a/fsck.c +++ b/fsck.c @@ -165,18 +165,12 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func) sha1 = tree_entry_extract(&desc, &name, &mode); - if (is_null_sha1(sha1)) - has_null_sha1 = 1; - if (strchr(name, '/')) - has_full_path = 1; - if (!*name) - has_empty_name = 1; - if (!strcmp(name, ".")) - has_dot = 1; - if (!strcmp(name, "..")) - has_dotdot = 1; - if (!strcmp(name, ".git")) - has_dotgit = 1; + has_null_sha1 |= is_null_sha1(sha1); + has_full_path |= !!strchr(name, '/'); + has_empty_name |= !*name; + has_dot |= !strcmp(name, "."); + has_dotdot |= !strcmp(name, ".."); + has_dotgit |= !strcmp(name, ".git"); has_zero_pad |= *(char *)desc.buffer == '0'; update_tree_entry(&desc); @@ -243,7 +237,7 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func) return retval; } -static int fsck_ident(char **ident, struct object *obj, fsck_error error_func) +static int fsck_ident(const char **ident, struct object *obj, fsck_error error_func) { char *end; @@ -284,21 +278,23 @@ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func) static int fsck_commit(struct commit *commit, fsck_error error_func) { - char *buffer = commit->buffer; + const char *buffer = commit->buffer, *tmp; unsigned char tree_sha1[20], sha1[20]; struct commit_graft *graft; int parents = 0; int err; - if (memcmp(buffer, "tree ", 5)) + buffer = skip_prefix(buffer, "tree "); + if (!buffer) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line"); - if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n') + if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n') return error_func(&commit->object, FSCK_ERROR, "invalid 'tree' line format - bad sha1"); - buffer += 46; - while (!memcmp(buffer, "parent ", 7)) { - if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n') + buffer += 41; + while ((tmp = skip_prefix(buffer, "parent "))) { + buffer = tmp; + if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') return error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1"); - buffer += 48; + buffer += 41; parents++; } graft = lookup_commit_graft(commit->object.sha1); @@ -322,15 +318,15 @@ static int fsck_commit(struct commit *commit, fsck_error error_func) if (p || parents) return error_func(&commit->object, FSCK_ERROR, "parent objects missing"); } - if (memcmp(buffer, "author ", 7)) + buffer = skip_prefix(buffer, "author "); + if (!buffer) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line"); - buffer += 7; err = fsck_ident(&buffer, &commit->object, error_func); if (err) return err; - if (memcmp(buffer, "committer ", strlen("committer "))) + buffer = skip_prefix(buffer, "committer "); + if (!buffer) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line"); - buffer += strlen("committer "); err = fsck_ident(&buffer, &commit->object, error_func); if (err) return err; diff --git a/git-rebase.sh b/git-rebase.sh index 5f6732bf3d..2c75e9fa0f 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -453,6 +453,10 @@ then test "$fork_point" = auto && fork_point=t ;; *) upstream_name="$1" + if test "$upstream_name" = "-" + then + upstream_name="@{-1}" + fi shift ;; esac diff --git a/git-submodule.sh b/git-submodule.sh index 6135cfa912..b55d83ac46 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -246,9 +246,6 @@ module_name() # $3 = URL to clone # $4 = reference repository to reuse (empty for independent) # $5 = depth argument for shallow clones (empty for deep) -# $6 = (remote-tracking) starting point for the local branch (empty for HEAD) -# $7 = local branch to create (empty for a detached HEAD, unless $6 is -# also empty, in which case the local branch is left unchanged) # # Prior to calling, cmd_update checks that a possibly existing # path is not a git repository. @@ -262,8 +259,6 @@ module_clone() url=$3 reference="$4" depth="$5" - start_point="$6" - local_branch="$7" quiet= if test -n "$GIT_QUIET" then @@ -317,16 +312,7 @@ module_clone() echo "gitdir: $rel/$a" >"$sm_path/.git" rel=$(echo $a | sed -e 's|[^/][^/]*|..|g') - ( - clear_local_git_env - cd "$sm_path" && - GIT_WORK_TREE=. git config core.worktree "$rel/$b" && - # ash fails to wordsplit ${local_branch:+-B "$local_branch"...} - case "$local_branch" in - '') git checkout -f -q ${start_point:+"$start_point"} ;; - ?*) git checkout -f -q -B "$local_branch" ${start_point:+"$start_point"} ;; - esac - ) || die "$(eval_gettext "Unable to setup cloned submodule '\$sm_path'")" + (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b") } isnumber() @@ -489,15 +475,16 @@ Use -f if you really want to add it." >&2 echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")" fi fi - if test -n "$branch" - then - start_point="origin/$branch" - local_branch="$branch" - else - start_point="" - local_branch="" - fi - module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" "$start_point" "$local_branch" || exit + module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" || exit + ( + clear_local_git_env + cd "$sm_path" && + # ash fails to wordsplit ${branch:+-b "$branch"...} + case "$branch" in + '') git checkout -f -q ;; + ?*) git checkout -f -q -B "$branch" "origin/$branch" ;; + esac + ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")" fi git config submodule."$sm_name".url "$realrepo" @@ -818,9 +805,7 @@ cmd_update() fi name=$(module_name "$sm_path") || exit url=$(git config submodule."$name".url) - config_branch=$(get_submodule_config "$name" branch) - branch="${config_branch:-master}" - local_branch="$branch" + branch=$(get_submodule_config "$name" branch master) if ! test -z "$update" then update_module=$update @@ -834,19 +819,11 @@ cmd_update() displaypath=$(relative_path "$prefix$sm_path") - case "$update_module" in - none) + if test "$update_module" = "none" + then echo "Skipping submodule '$displaypath'" continue - ;; - checkout) - local_branch="" - ;; - rebase | merge | !*) - ;; - *) - die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")" - esac + fi if test -z "$url" then @@ -860,8 +837,7 @@ Maybe you want to use 'update --init'?")" if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git then - start_point="origin/${branch}" - module_clone "$sm_path" "$name" "$url" "$reference" "$depth" "$start_point" "$local_branch" || exit + module_clone "$sm_path" "$name" "$url" "$reference" "$depth" || exit cloned_modules="$cloned_modules;$name" subsha1= else @@ -907,7 +883,7 @@ Maybe you want to use 'update --init'?")" case ";$cloned_modules;" in *";$name;"*) # then there is no local change to integrate - update_module='!git reset --hard -q' + update_module=checkout ;; esac must_die_on_failure= diff --git a/run-command.c b/run-command.c index 3914d9c511..75abc478c6 100644 --- a/run-command.c +++ b/run-command.c @@ -760,13 +760,11 @@ char *find_hook(const char *name) return path; } -int run_hook(const char *index_file, const char *name, ...) +int run_hook_ve(const char *const *env, const char *name, va_list args) { struct child_process hook; struct argv_array argv = ARGV_ARRAY_INIT; - const char *p, *env[2]; - char index[PATH_MAX]; - va_list args; + const char *p; int ret; p = find_hook(name); @@ -775,23 +773,45 @@ int run_hook(const char *index_file, const char *name, ...) argv_array_push(&argv, p); - va_start(args, name); while ((p = va_arg(args, const char *))) argv_array_push(&argv, p); - va_end(args); memset(&hook, 0, sizeof(hook)); hook.argv = argv.argv; + hook.env = env; hook.no_stdin = 1; hook.stdout_to_stderr = 1; - if (index_file) { - snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); - env[0] = index; - env[1] = NULL; - hook.env = env; - } ret = run_command(&hook); argv_array_clear(&argv); return ret; } + +int run_hook_le(const char *const *env, const char *name, ...) +{ + va_list args; + int ret; + + va_start(args, name); + ret = run_hook_ve(env, name, args); + va_end(args); + + return ret; +} + +int run_hook_with_custom_index(const char *index_file, const char *name, ...) +{ + const char *hook_env[3] = { NULL }; + char index[PATH_MAX]; + va_list args; + int ret; + + snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); + hook_env[0] = index; + + va_start(args, name); + ret = run_hook_ve(hook_env, name, args); + va_end(args); + + return ret; +} diff --git a/run-command.h b/run-command.h index 6b985afd07..3653bfa6e1 100644 --- a/run-command.h +++ b/run-command.h @@ -47,7 +47,12 @@ int run_command(struct child_process *); extern char *find_hook(const char *name); LAST_ARG_MUST_BE_NULL -extern int run_hook(const char *index_file, const char *name, ...); +extern int run_hook_le(const char *const *env, const char *name, ...); +extern int run_hook_ve(const char *const *env, const char *name, va_list args); + +LAST_ARG_MUST_BE_NULL +__attribute__((deprecated)) +extern int run_hook_with_custom_index(const char *index_file, const char *name, ...); #define RUN_COMMAND_NO_STDIN 1 #define RUN_GIT_CMD 2 /*If this is to be git sub-command */ diff --git a/t/Makefile b/t/Makefile index 2373a04f7a..8fd1a72357 100644 --- a/t/Makefile +++ b/t/Makefile @@ -36,11 +36,11 @@ test: pre-clean $(TEST_LINT) $(MAKE) aggregate-results-and-cleanup prove: pre-clean $(TEST_LINT) - @echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS) + @echo "*** prove ***"; $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS) $(MAKE) clean-except-prove-cache $(T): - @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) + @echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) pre-clean: $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 9fb582b192..bbc9cb60dd 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -12,8 +12,8 @@ check_config () { echo "expected a directory $1, a file $1/config and $1/refs" return 1 fi - bare=$(GIT_CONFIG="$1/config" git config --bool core.bare) - worktree=$(GIT_CONFIG="$1/config" git config core.worktree) || + bare=$(cd "$1" && git config --bool core.bare) + worktree=$(cd "$1" && git config core.worktree) || worktree=unset test "$bare" = "$2" && test "$worktree" = "$3" || { @@ -24,18 +24,12 @@ check_config () { } test_expect_success 'plain' ' - ( - sane_unset GIT_DIR GIT_WORK_TREE && - mkdir plain && - cd plain && - git init - ) && + git init plain && check_config plain/.git false unset ' test_expect_success 'plain nested in bare' ' ( - sane_unset GIT_DIR GIT_WORK_TREE && git init --bare bare-ancestor.git && cd bare-ancestor.git && mkdir plain-nested && @@ -47,7 +41,6 @@ test_expect_success 'plain nested in bare' ' test_expect_success 'plain through aliased command, outside any git repo' ' ( - sane_unset GIT_DIR GIT_WORK_TREE && HOME=$(pwd)/alias-config && export HOME && mkdir alias-config && @@ -65,7 +58,6 @@ test_expect_success 'plain through aliased command, outside any git repo' ' test_expect_failure 'plain nested through aliased command' ' ( - sane_unset GIT_DIR GIT_WORK_TREE && git init plain-ancestor-aliased && cd plain-ancestor-aliased && echo "[alias] aliasedinit = init" >>.git/config && @@ -78,7 +70,6 @@ test_expect_failure 'plain nested through aliased command' ' test_expect_failure 'plain nested in bare through aliased command' ' ( - sane_unset GIT_DIR GIT_WORK_TREE && git init --bare bare-ancestor-aliased.git && cd bare-ancestor-aliased.git && echo "[alias] aliasedinit = init" >>config && @@ -90,66 +81,36 @@ test_expect_failure 'plain nested in bare through aliased command' ' ' test_expect_success 'plain with GIT_WORK_TREE' ' - if ( - sane_unset GIT_DIR && - mkdir plain-wt && - cd plain-wt && - GIT_WORK_TREE=$(pwd) git init - ) - then - echo Should have failed -- GIT_WORK_TREE should not be used - false - fi + mkdir plain-wt && + test_must_fail env GIT_WORK_TREE="$(pwd)/plain-wt" git init plain-wt ' test_expect_success 'plain bare' ' - ( - sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && - mkdir plain-bare-1 && - cd plain-bare-1 && - git --bare init - ) && + git --bare init plain-bare-1 && check_config plain-bare-1 true unset ' test_expect_success 'plain bare with GIT_WORK_TREE' ' - if ( - sane_unset GIT_DIR GIT_CONFIG && - mkdir plain-bare-2 && - cd plain-bare-2 && - GIT_WORK_TREE=$(pwd) git --bare init - ) - then - echo Should have failed -- GIT_WORK_TREE should not be used - false - fi + mkdir plain-bare-2 && + test_must_fail \ + env GIT_WORK_TREE="$(pwd)/plain-bare-2" \ + git --bare init plain-bare-2 ' test_expect_success 'GIT_DIR bare' ' - - ( - sane_unset GIT_CONFIG && - mkdir git-dir-bare.git && - GIT_DIR=git-dir-bare.git git init - ) && + mkdir git-dir-bare.git && + GIT_DIR=git-dir-bare.git git init && check_config git-dir-bare.git true unset ' test_expect_success 'init --bare' ' - - ( - sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && - mkdir init-bare.git && - cd init-bare.git && - git init --bare - ) && + git init --bare init-bare.git && check_config init-bare.git true unset ' test_expect_success 'GIT_DIR non-bare' ' ( - sane_unset GIT_CONFIG && mkdir non-bare && cd non-bare && GIT_DIR=.git git init @@ -160,7 +121,6 @@ test_expect_success 'GIT_DIR non-bare' ' test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' ( - sane_unset GIT_CONFIG && mkdir git-dir-wt-1.git && GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init ) && @@ -168,23 +128,16 @@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' ' test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' ' - - if ( - sane_unset GIT_CONFIG && - mkdir git-dir-wt-2.git && - GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init - ) - then - echo Should have failed -- --bare should not be used - false - fi + mkdir git-dir-wt-2.git && + test_must_fail env \ + GIT_WORK_TREE="$(pwd)" \ + GIT_DIR=git-dir-wt-2.git \ + git --bare init ' test_expect_success 'reinit' ' ( - sane_unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG && - mkdir again && cd again && git init >out1 2>err1 && @@ -200,35 +153,22 @@ test_expect_success 'reinit' ' test_expect_success 'init with --template' ' mkdir template-source && echo content >template-source/file && - ( - mkdir template-custom && - cd template-custom && - git init --template=../template-source - ) && + git init --template=../template-source template-custom && test_cmp template-source/file template-custom/.git/file ' test_expect_success 'init with --template (blank)' ' - ( - mkdir template-plain && - cd template-plain && - git init - ) && - test -f template-plain/.git/info/exclude && - ( - mkdir template-blank && - cd template-blank && - git init --template= - ) && - ! test -f template-blank/.git/info/exclude + git init template-plain && + test_path_is_file template-plain/.git/info/exclude && + git init --template= template-blank && + test_path_is_missing template-blank/.git/info/exclude ' test_expect_success 'init with init.templatedir set' ' mkdir templatedir-source && echo Content >templatedir-source/file && + test_config_global init.templatedir "${HOME}/templatedir-source" && ( - test_config="${HOME}/.gitconfig" && - git config -f "$test_config" init.templatedir "${HOME}/templatedir-source" && mkdir templatedir-set && cd templatedir-set && sane_unset GIT_TEMPLATE_DIR && @@ -240,78 +180,55 @@ test_expect_success 'init with init.templatedir set' ' ' test_expect_success 'init --bare/--shared overrides system/global config' ' - ( - test_config="$HOME"/.gitconfig && - git config -f "$test_config" core.bare false && - git config -f "$test_config" core.sharedRepository 0640 && - mkdir init-bare-shared-override && - cd init-bare-shared-override && - git init --bare --shared=0666 - ) && + test_config_global core.bare false && + test_config_global core.sharedRepository 0640 && + git init --bare --shared=0666 init-bare-shared-override && check_config init-bare-shared-override true unset && test x0666 = \ x`git config -f init-bare-shared-override/config core.sharedRepository` ' test_expect_success 'init honors global core.sharedRepository' ' - ( - test_config="$HOME"/.gitconfig && - git config -f "$test_config" core.sharedRepository 0666 && - mkdir shared-honor-global && - cd shared-honor-global && - git init - ) && + test_config_global core.sharedRepository 0666 && + git init shared-honor-global && test x0666 = \ x`git config -f shared-honor-global/.git/config core.sharedRepository` ' test_expect_success 'init rejects insanely long --template' ' - ( - insane=$(printf "x%09999dx" 1) && - mkdir test && - cd test && - test_must_fail git init --template=$insane - ) + test_must_fail git init --template=$(printf "x%09999dx" 1) test ' test_expect_success 'init creates a new directory' ' rm -fr newdir && - ( - git init newdir && - test -d newdir/.git/refs - ) + git init newdir && + test_path_is_dir newdir/.git/refs ' test_expect_success 'init creates a new bare directory' ' rm -fr newdir && - ( - git init --bare newdir && - test -d newdir/refs - ) + git init --bare newdir && + test_path_is_dir newdir/refs ' test_expect_success 'init recreates a directory' ' rm -fr newdir && - ( - mkdir newdir && - git init newdir && - test -d newdir/.git/refs - ) + mkdir newdir && + git init newdir && + test_path_is_dir newdir/.git/refs ' test_expect_success 'init recreates a new bare directory' ' rm -fr newdir && - ( - mkdir newdir && - git init --bare newdir && - test -d newdir/refs - ) + mkdir newdir && + git init --bare newdir && + test_path_is_dir newdir/refs ' test_expect_success 'init creates a new deep directory' ' rm -fr newdir && git init newdir/a/b/c && - test -d newdir/a/b/c/.git/refs + test_path_is_dir newdir/a/b/c/.git/refs ' test_expect_success POSIXPERM 'init creates a new deep directory (umask vs. shared)' ' @@ -321,7 +238,7 @@ test_expect_success POSIXPERM 'init creates a new deep directory (umask vs. shar # the repository itself should follow "shared" umask 002 && git init --bare --shared=0660 newdir/a/b/c && - test -d newdir/a/b/c/refs && + test_path_is_dir newdir/a/b/c/refs && ls -ld newdir/a newdir/a/b > lsab.out && ! grep -v "^drwxrw[sx]r-x" lsab.out && ls -ld newdir/a/b/c > lsc.out && @@ -331,44 +248,38 @@ test_expect_success POSIXPERM 'init creates a new deep directory (umask vs. shar test_expect_success 'init notices EEXIST (1)' ' rm -fr newdir && - ( - >newdir && - test_must_fail git init newdir && - test -f newdir - ) + >newdir && + test_must_fail git init newdir && + test_path_is_file newdir ' test_expect_success 'init notices EEXIST (2)' ' rm -fr newdir && - ( - mkdir newdir && - >newdir/a - test_must_fail git init newdir/a/b && - test -f newdir/a - ) + mkdir newdir && + >newdir/a && + test_must_fail git init newdir/a/b && + test_path_is_file newdir/a ' test_expect_success POSIXPERM,SANITY 'init notices EPERM' ' rm -fr newdir && - ( - mkdir newdir && - chmod -w newdir && - test_must_fail git init newdir/a/b - ) + mkdir newdir && + chmod -w newdir && + test_must_fail git init newdir/a/b ' test_expect_success 'init creates a new bare directory with global --bare' ' rm -rf newdir && git --bare init newdir && - test -d newdir/refs + test_path_is_dir newdir/refs ' test_expect_success 'init prefers command line to GIT_DIR' ' rm -rf newdir && mkdir otherdir && GIT_DIR=otherdir git --bare init newdir && - test -d newdir/refs && - ! test -d otherdir/refs + test_path_is_dir newdir/refs && + test_path_is_missing otherdir/refs ' test_expect_success 'init with separate gitdir' ' @@ -376,7 +287,7 @@ test_expect_success 'init with separate gitdir' ' git init --separate-git-dir realgitdir newdir && echo "gitdir: `pwd`/realgitdir" >expected && test_cmp expected newdir/.git && - test -d realgitdir/refs + test_path_is_dir realgitdir/refs ' test_expect_success 're-init on .git file' ' @@ -390,8 +301,8 @@ test_expect_success 're-init to update git link' ' ) && echo "gitdir: `pwd`/surrealgitdir" >expected && test_cmp expected newdir/.git && - test -d surrealgitdir/refs && - ! test -d realgitdir/refs + test_path_is_dir surrealgitdir/refs && + test_path_is_missing realgitdir/refs ' test_expect_success 're-init to move gitdir' ' @@ -403,7 +314,7 @@ test_expect_success 're-init to move gitdir' ' ) && echo "gitdir: `pwd`/realgitdir" >expected && test_cmp expected newdir/.git && - test -d realgitdir/refs + test_path_is_dir realgitdir/refs ' test_expect_success SYMLINKS 're-init to move gitdir symlink' ' @@ -417,8 +328,8 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' ' ) && echo "gitdir: `pwd`/realgitdir" >expected && test_cmp expected newdir/.git && - test -d realgitdir/refs && - ! test -d newdir/here + test_cmp expected newdir/here && + test_path_is_dir realgitdir/refs ' test_done diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index c9c426c273..58cd5435be 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -461,7 +461,7 @@ test_expect_success 'new variable inserts into proper section' ' test_cmp expect .git/config ' -test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' ' +test_expect_success 'alternative --file (non-existing file should fail)' ' test_must_fail git config --file non-existing-config -l ' @@ -508,10 +508,10 @@ test_expect_success 'refer config from subdirectory' ' ' -test_expect_success 'refer config from subdirectory via GIT_CONFIG' ' +test_expect_success 'refer config from subdirectory via --file' ' ( cd x && - GIT_CONFIG=../other-config git config --get ein.bahn >actual && + git config --file=../other-config --get ein.bahn >actual && test_cmp expect actual ) ' @@ -523,8 +523,8 @@ cat > expect << EOF park = ausweis EOF -test_expect_success '--set in alternative GIT_CONFIG' ' - GIT_CONFIG=other-config git config anwohner.park ausweis && +test_expect_success '--set in alternative file' ' + git config --file=other-config anwohner.park ausweis && test_cmp expect other-config ' @@ -955,11 +955,11 @@ test_expect_success 'inner whitespace kept verbatim' ' test_expect_success SYMLINKS 'symlinked configuration' ' ln -s notyet myconfig && - GIT_CONFIG=myconfig git config test.frotz nitfol && + git config --file=myconfig test.frotz nitfol && test -h myconfig && test -f notyet && - test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol && - GIT_CONFIG=myconfig git config test.xyzzy rezrov && + test "z$(git config --file=notyet test.frotz)" = znitfol && + git config --file=myconfig test.xyzzy rezrov && test -h myconfig && test -f notyet && cat >expect <<-\EOF && @@ -967,31 +967,22 @@ test_expect_success SYMLINKS 'symlinked configuration' ' rezrov EOF { - GIT_CONFIG=notyet git config test.frotz && - GIT_CONFIG=notyet git config test.xyzzy + git config --file=notyet test.frotz && + git config --file=notyet test.xyzzy } >actual && test_cmp expect actual ' test_expect_success 'nonexistent configuration' ' - ( - GIT_CONFIG=doesnotexist && - export GIT_CONFIG && - test_must_fail git config --list && - test_must_fail git config test.xyzzy - ) + test_must_fail git config --file=doesnotexist --list && + test_must_fail git config --file=doesnotexist test.xyzzy ' test_expect_success SYMLINKS 'symlink to nonexistent configuration' ' ln -s doesnotexist linktonada && ln -s linktonada linktolinktonada && - ( - GIT_CONFIG=linktonada && - export GIT_CONFIG && - test_must_fail git config --list && - GIT_CONFIG=linktolinktonada && - test_must_fail git config --list - ) + test_must_fail git config --file=linktonada --list && + test_must_fail git config --file=linktolinktonada --list ' test_expect_success 'check split_cmdline return' " diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh index 0e47662406..0d9388afc4 100755 --- a/t/t1302-repo-version.sh +++ b/t/t1302-repo-version.sh @@ -19,7 +19,7 @@ test_expect_success 'setup' ' test_create_repo "test" && test_create_repo "test2" && - GIT_CONFIG=test2/.git/config git config core.repositoryformatversion 99 + git config --file=test2/.git/config core.repositoryformatversion 99 ' test_expect_success 'gitdir selection on normal repos' ' diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index 83b1300cef..922423e7d0 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -3,44 +3,64 @@ test_description='test git rev-parse --parseopt' . ./test-lib.sh -cat > expect <<\END_EXPECT -cat <<\EOF -usage: some-command [options] ... - - some-command does foo and bar! - - -h, --help show the help - --foo some nifty option --foo - --bar ... some cool option --bar with an argument - -b, --baz a short and long option - -An option group Header - -C[...] option C with an optional argument - -d, --data[=...] short and long option with an optional argument - -Extras - --extra1 line above used to cause a segfault but no longer does - -EOF +sed -e 's/^|//' >expect <<\END_EXPECT +|cat <<\EOF +|usage: some-command [options] ... +| +| some-command does foo and bar! +| +| -h, --help show the help +| --foo some nifty option --foo +| --bar ... some cool option --bar with an argument +| -b, --baz a short and long option +| +|An option group Header +| -C[...] option C with an optional argument +| -d, --data[=...] short and long option with an optional argument +| +|Argument hints +| -b short option required argument +| --bar2 long option required argument +| -e, --fuz +| short and long option required argument +| -s[] short option optional argument +| --long[=] long option optional argument +| -g, --fluf[=] short and long option optional argument +| --longest +| a very long argument hint +| +|Extras +| --extra1 line above used to cause a segfault but no longer does +| +|EOF END_EXPECT -cat > optionspec << EOF -some-command [options] ... - -some-command does foo and bar! --- -h,help show the help - -foo some nifty option --foo -bar= some cool option --bar with an argument -b,baz a short and long option - - An option group Header -C? option C with an optional argument -d,data? short and long option with an optional argument - -Extras -extra1 line above used to cause a segfault but no longer does +sed -e 's/^|//' >optionspec <<\EOF +|some-command [options] ... +| +|some-command does foo and bar! +|-- +|h,help show the help +| +|foo some nifty option --foo +|bar= some cool option --bar with an argument +|b,baz a short and long option +| +| An option group Header +|C? option C with an optional argument +|d,data? short and long option with an optional argument +| +| Argument hints +|b=arg short option required argument +|bar2=arg long option required argument +|e,fuz=with-space short and long option required argument +|s?some short option optional argument +|long?data long option optional argument +|g,fluf?path short and long option optional argument +|longest=very-long-argument-hint a very long argument hint +| +|Extras +|extra1 line above used to cause a segfault but no longer does EOF test_expect_success 'test --parseopt help output' ' diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh index cf2ee7885a..e1b2a99f10 100755 --- a/t/t1510-repo-setup.sh +++ b/t/t1510-repo-setup.sh @@ -777,9 +777,7 @@ test_expect_success '#30: core.worktree and core.bare conflict (gitfile version) setup_repo 30 "$here/30" gitfile true && ( cd 30 && - GIT_DIR=.git && - export GIT_DIR && - test_must_fail git symbolic-ref HEAD 2>result + test_must_fail env GIT_DIR=.git git symbolic-ref HEAD 2>result ) && grep "core.bare and core.worktree" 30/result ' diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 83037b1cd9..ac31b711f2 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -859,11 +859,7 @@ test_expect_success 'detect typo in branch name when using --edit-description' ' write_script editor <<-\EOF && echo "New contents" >"$1" EOF - ( - EDITOR=./editor && - export EDITOR && - test_must_fail git branch --edit-description no-such-branch - ) + test_must_fail env EDITOR=./editor git branch --edit-description no-such-branch ' test_expect_success 'refuse --edit-description on unborn branch for now' ' @@ -871,11 +867,7 @@ test_expect_success 'refuse --edit-description on unborn branch for now' ' echo "New contents" >"$1" EOF git checkout --orphan unborn && - ( - EDITOR=./editor && - export EDITOR && - test_must_fail git branch --edit-description - ) + test_must_fail env EDITOR=./editor git branch --edit-description ' test_expect_success '--merged catches invalid object names' ' diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 3bb79a47af..cfd67ff3df 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -17,7 +17,7 @@ GIT_EDITOR=./fake_editor.sh export GIT_EDITOR test_expect_success 'cannot annotate non-existing HEAD' ' - (MSG=3 && export MSG && test_must_fail git notes add) + test_must_fail env MSG=3 git notes add ' test_expect_success setup ' @@ -32,22 +32,16 @@ test_expect_success setup ' ' test_expect_success 'need valid notes ref' ' - (MSG=1 GIT_NOTES_REF=/ && export MSG GIT_NOTES_REF && - test_must_fail git notes add) && - (MSG=2 GIT_NOTES_REF=/ && export MSG GIT_NOTES_REF && - test_must_fail git notes show) + test_must_fail env MSG=1 GIT_NOTES_REF=/ git notes show && + test_must_fail env MSG=2 GIT_NOTES_REF=/ git notes show ' test_expect_success 'refusing to add notes in refs/heads/' ' - (MSG=1 GIT_NOTES_REF=refs/heads/bogus && - export MSG GIT_NOTES_REF && - test_must_fail git notes add) + test_must_fail env MSG=1 GIT_NOTES_REF=refs/heads/bogus git notes add ' test_expect_success 'refusing to edit notes in refs/remotes/' ' - (MSG=1 GIT_NOTES_REF=refs/remotes/bogus && - export MSG GIT_NOTES_REF && - test_must_fail git notes edit) + test_must_fail env MSG=1 GIT_NOTES_REF=refs/heads/bogus git notes edit ' # 1 indicates caught gracefully by die, 128 means git-show barked @@ -865,11 +859,7 @@ test_expect_success 'create note from non-existing note with "git notes add -c" git add a10 && test_tick && git commit -m 10th && - ( - MSG="yet another note" && - export MSG && - test_must_fail git notes add -c deadbeef - ) && + test_must_fail env MSG="yet another note" git notes add -c deadbeef && test_must_fail git notes list HEAD ' diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 6d94b1fcd9..80e0a951ea 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -88,6 +88,23 @@ test_expect_success 'rebase from ambiguous branch name' ' git rebase master ' +test_expect_success 'rebase off of the previous branch using "-"' ' + git checkout master && + git checkout HEAD^ && + git rebase @{-1} >expect.messages && + git merge-base master HEAD >expect.forkpoint && + + git checkout master && + git checkout HEAD^ && + git rebase - >actual.messages && + git merge-base master HEAD >actual.forkpoint && + + test_cmp expect.forkpoint actual.forkpoint && + # the next one is dubious---we may want to say "-", + # instead of @{-1}, in the message + test_i18ncmp expect.messages actual.messages +' + test_expect_success 'rebase a single mode change' ' git checkout master && git branch -D topic && diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 50e22b1cad..c0023a5b4f 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -102,12 +102,8 @@ test_expect_success 'rebase -i with the exec command runs from tree root' ' test_expect_success 'rebase -i with the exec command checks tree cleanness' ' git checkout master && - ( set_fake_editor && - FAKE_LINES="exec_echo_foo_>file1 1" && - export FAKE_LINES && - test_must_fail git rebase -i HEAD^ - ) && + test_must_fail env FAKE_LINES="exec_echo_foo_>file1 1" git rebase -i HEAD^ && test_cmp_rev master^ HEAD && git reset --hard && git rebase --continue @@ -116,12 +112,9 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' ' test_expect_success 'rebase -i with exec of inexistent command' ' git checkout master && test_when_finished "git rebase --abort" && - ( set_fake_editor && - FAKE_LINES="exec_this-command-does-not-exist 1" && - export FAKE_LINES && - test_must_fail git rebase -i HEAD^ >actual 2>&1 - ) && + test_must_fail env FAKE_LINES="exec_this-command-does-not-exist 1" \ + git rebase -i HEAD^ >actual 2>&1 && ! grep "Maybe git-rebase is broken" actual ' @@ -375,11 +368,7 @@ test_expect_success 'commit message used after conflict' ' git checkout -b conflict-fixup conflict-branch && base=$(git rev-parse HEAD~4) && set_fake_editor && - ( - FAKE_LINES="1 fixup 3 fixup 4" && - export FAKE_LINES && - test_must_fail git rebase -i $base - ) && + test_must_fail env FAKE_LINES="1 fixup 3 fixup 4" git rebase -i $base && echo three > conflict && git add conflict && FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \ @@ -394,11 +383,7 @@ test_expect_success 'commit message retained after conflict' ' git checkout -b conflict-squash conflict-branch && base=$(git rev-parse HEAD~4) && set_fake_editor && - ( - FAKE_LINES="1 fixup 3 squash 4" && - export FAKE_LINES && - test_must_fail git rebase -i $base - ) && + test_must_fail env FAKE_LINES="1 fixup 3 squash 4" git rebase -i $base && echo three > conflict && git add conflict && FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \ @@ -469,11 +454,7 @@ test_expect_success 'interrupted squash works as expected' ' git checkout -b interrupted-squash conflict-branch && one=$(git rev-parse HEAD~3) && set_fake_editor && - ( - FAKE_LINES="1 squash 3 2" && - export FAKE_LINES && - test_must_fail git rebase -i HEAD~3 - ) && + test_must_fail env FAKE_LINES="1 squash 3 2" git rebase -i HEAD~3 && (echo one; echo two; echo four) > conflict && git add conflict && test_must_fail git rebase --continue && @@ -487,11 +468,7 @@ test_expect_success 'interrupted squash works as expected (case 2)' ' git checkout -b interrupted-squash2 conflict-branch && one=$(git rev-parse HEAD~3) && set_fake_editor && - ( - FAKE_LINES="3 squash 1 2" && - export FAKE_LINES && - test_must_fail git rebase -i HEAD~3 - ) && + test_must_fail env FAKE_LINES="3 squash 1 2" git rebase -i HEAD~3 && (echo one; echo four) > conflict && git add conflict && test_must_fail git rebase --continue && @@ -528,11 +505,7 @@ test_expect_success 'aborted --continue does not squash commits after "edit"' ' FAKE_LINES="edit 1" git rebase -i HEAD^ && echo "edited again" > file7 && git add file7 && - ( - FAKE_COMMIT_MESSAGE=" " && - export FAKE_COMMIT_MESSAGE && - test_must_fail git rebase --continue - ) && + test_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue && test $old = $(git rev-parse HEAD) && git rebase --abort ' @@ -547,11 +520,7 @@ test_expect_success 'auto-amend only edited commits after "edit"' ' echo "and again" > file7 && git add file7 && test_tick && - ( - FAKE_COMMIT_MESSAGE="and again" && - export FAKE_COMMIT_MESSAGE && - test_must_fail git rebase --continue - ) && + test_must_fail env FAKE_COMMIT_MESSAGE="and again" git rebase --continue && git rebase --abort ' @@ -559,11 +528,7 @@ test_expect_success 'clean error after failed "exec"' ' test_tick && test_when_finished "git rebase --abort || :" && set_fake_editor && - ( - FAKE_LINES="1 exec_false" && - export FAKE_LINES && - test_must_fail git rebase -i HEAD^ - ) && + test_must_fail env FAKE_LINES="1 exec_false" git rebase -i HEAD^ && echo "edited again" > file7 && git add file7 && test_must_fail git rebase --continue 2>error && @@ -947,12 +912,8 @@ test_expect_success 'rebase -i --root retain root commit author and message' ' test_expect_success 'rebase -i --root temporary sentinel commit' ' git checkout B && - ( - set_fake_editor && - FAKE_LINES="2" && - export FAKE_LINES && - test_must_fail git rebase -i --root - ) && + set_fake_editor && + test_must_fail env FAKE_LINES="2" git rebase -i --root && git cat-file commit HEAD | grep "^tree 4b825dc642cb" && git rebase --abort ' @@ -1042,11 +1003,7 @@ test_expect_success 'rebase -i error on commits with \ in message' ' test_when_finished "git rebase --abort; git reset --hard $current_head; rm -f error" && test_commit TO-REMOVE will-conflict old-content && test_commit "\temp" will-conflict new-content dummy && - ( - EDITOR=true && - export EDITOR && - test_must_fail git rebase -i HEAD^ --onto HEAD^^ 2>error - ) && + test_must_fail env EDITOR=true git rebase -i HEAD^ --onto HEAD^^ 2>error && test_expect_code 1 grep " emp" error ' diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh index 098b75507b..b6833e9a5f 100755 --- a/t/t3413-rebase-hook.sh +++ b/t/t3413-rebase-hook.sh @@ -118,11 +118,7 @@ test_expect_success 'pre-rebase hook stops rebase (1)' ' test_expect_success 'pre-rebase hook stops rebase (2)' ' git checkout test && git reset --hard side && - ( - EDITOR=: - export EDITOR - test_must_fail git rebase -i master - ) && + test_must_fail env EDITOR=: git rebase -i master && test "z$(git symbolic-ref HEAD)" = zrefs/heads/test && test 0 = $(git rev-list HEAD...side | wc -l) ' diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 73194b2c3d..9c80633146 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -764,22 +764,14 @@ test_expect_success 'format-patch --signature="" suppresses signatures' ' test_expect_success TTY 'format-patch --stdout paginates' ' rm -f pager_used && - ( - GIT_PAGER="wc >pager_used" && - export GIT_PAGER && - test_terminal git format-patch --stdout --all - ) && + test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all && test_path_is_file pager_used ' test_expect_success TTY 'format-patch --stdout pagination can be disabled' ' rm -f pager_used && - ( - GIT_PAGER="wc >pager_used" && - export GIT_PAGER && - test_terminal git --no-pager format-patch --stdout --all && - test_terminal git -c "pager.format-patch=false" format-patch --stdout --all - ) && + test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all && + test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all && test_path_is_missing pager_used && test_path_is_missing .git/pager_used ' diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 38a092a0da..34591c23da 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -7,179 +7,103 @@ test_description='Test custom diff function name patterns' . ./test-lib.sh -LF=' -' -cat >Beer.java <<\EOF -public class Beer -{ - int special; - public static void main(String args[]) - { - String s=" "; - for(int x = 99; x > 0; x--) - { - System.out.print(x + " bottles of beer on the wall " - + x + " bottles of beer\n" - + "Take one down, pass it around, " + (x - 1) - + " bottles of beer on the wall.\n"); - } - System.out.print("Go to the store, buy some more,\n" - + "99 bottles of beer on the wall.\n"); - } -} -EOF -sed 's/beer\\/beer,\\/' Beer-correct.java -cat >Beer.perl <<\EOT -package Beer; - -use strict; -use warnings; -use parent qw(Exporter); -our @EXPORT_OK = qw(round finalround); - -sub other; # forward declaration - -# hello - -sub round { - my ($n) = @_; - print "$n bottles of beer on the wall "; - print "$n bottles of beer\n"; - print "Take one down, pass it around, "; - $n = $n - 1; - print "$n bottles of beer on the wall.\n"; -} - -sub finalround -{ - print "Go to the store, buy some more\n"; - print "99 bottles of beer on the wall.\n"); -} - -sub withheredocument { - print <<"EOF" -decoy here-doc -EOF - # some lines of context - # to pad it out - print "hello\n"; -} - -__END__ - -=head1 NAME - -Beer - subroutine to output fragment of a drinking song - -=head1 SYNOPSIS - - use Beer qw(round finalround); - - sub song { - for (my $i = 99; $i > 0; $i--) { - round $i; - } - finalround; - } +test_expect_success 'setup' ' + # a non-trivial custom pattern + git config diff.custom1.funcname "!static +!String +[^ ].*s.*" && - song; + # a custom pattern which matches to end of line + git config diff.custom2.funcname "......Beer\$" && -=cut -EOT -sed -e ' - s/hello/goodbye/ - s/beer\\/beer,\\/ - s/more\\/more,\\/ - s/song;/song();/ -' Beer-correct.perl + # alternation in pattern + git config diff.custom3.funcname "Beer$" && + git config diff.custom3.xfuncname "^[ ]*((public|static).*)$" && -test_expect_funcname () { - lang=${2-java} - test_expect_code 1 git diff --no-index -U1 \ - "Beer.$lang" "Beer-correct.$lang" >diff && - grep "^@@.*@@ $1" diff -} + # for regexp compilation tests + echo A >A.java && + echo B >B.java +' -for p in ada bibtex cpp csharp fortran html java matlab objc pascal perl php python ruby tex +diffpatterns=" + ada + bibtex + cpp + csharp + fortran + html + java + matlab + objc + pascal + perl + php + python + ruby + tex + custom1 + custom2 + custom3 +" + +for p in $diffpatterns do test_expect_success "builtin $p pattern compiles" ' echo "*.java diff=$p" >.gitattributes && test_expect_code 1 git diff --no-index \ - Beer.java Beer-correct.java 2>msg && - ! grep fatal msg && - ! grep error msg + A.java B.java 2>msg && + ! test_i18ngrep fatal msg && + ! test_i18ngrep error msg ' test_expect_success "builtin $p wordRegex pattern compiles" ' echo "*.java diff=$p" >.gitattributes && test_expect_code 1 git diff --no-index --word-diff \ - Beer.java Beer-correct.java 2>msg && - ! grep fatal msg && - ! grep error msg + A.java B.java 2>msg && + ! test_i18ngrep fatal msg && + ! test_i18ngrep error msg ' done -test_expect_success 'default behaviour' ' - rm -f .gitattributes && - test_expect_funcname "public class Beer\$" -' - -test_expect_success 'set up .gitattributes declaring drivers to test' ' - cat >.gitattributes <<-\EOF - *.java diff=java - *.perl diff=perl - EOF -' - -test_expect_success 'preset java pattern' ' - test_expect_funcname "public static void main(" -' - -test_expect_success 'preset perl pattern' ' - test_expect_funcname "sub round {\$" perl -' - -test_expect_success 'perl pattern accepts K&R style brace placement, too' ' - test_expect_funcname "sub finalround\$" perl -' - -test_expect_success 'but is not distracted by end of <.gitattributes && test_config diff.java.funcname "!static" && - test_expect_code 128 git diff --no-index Beer.java Beer-correct.java 2>msg && - grep ": Last expression must not be negated:" msg + test_expect_code 128 git diff --no-index A.java B.java 2>msg && + test_i18ngrep ": Last expression must not be negated:" msg ' -test_expect_success 'pattern which matches to end of line' ' - test_config diff.java.funcname "Beer\$" && - test_expect_funcname "Beer\$" +test_expect_success 'setup hunk header tests' ' + for i in $diffpatterns + do + echo "$i-* diff=$i" + done > .gitattributes && + + # add all test files to the index + ( + cd "$TEST_DIRECTORY"/t4018 && + git --git-dir="$TRASH_DIRECTORY/.git" add . + ) && + + # place modified files in the worktree + for i in $(git ls-files) + do + sed -e "s/ChangeMe/IWasChanged/" <"$TEST_DIRECTORY/t4018/$i" >"$i" || return 1 + done ' -test_expect_success 'alternation in pattern' ' - test_config diff.java.funcname "Beer$" && - test_config diff.java.xfuncname "^[ ]*((public|static).*)$" && - test_expect_funcname "public static void main(" -' +# check each individual file +for i in $(git ls-files) +do + if grep broken "$i" >/dev/null 2>&1 + then + result=failure + else + result=success + fi + test_expect_$result "hunk header: $i" " + test_when_finished 'cat actual' && # for debugging only + git diff -U1 $i >actual && + grep '@@ .* @@.*RIGHT' actual + " +done test_done diff --git a/t/t4018/README b/t/t4018/README new file mode 100644 index 0000000000..283e01cca1 --- /dev/null +++ b/t/t4018/README @@ -0,0 +1,18 @@ +How to write RIGHT test cases +============================= + +Insert the word "ChangeMe" (exactly this form) at a distance of +at least two lines from the line that must appear in the hunk header. + +The text that must appear in the hunk header must contain the word +"right", but in all upper-case, like in the title above. + +To mark a test case that highlights a malfunction, insert the word +BROKEN in all lower-case somewhere in the file. + +This text is a bit twisted and out of order, but it is itself a +test case for the default hunk header pattern. Know what you are doing +if you change it. + +BTW, this tests that the head line goes to the hunk header, not the line +of equal signs. diff --git a/t/t4018/cpp-c++-function b/t/t4018/cpp-c++-function new file mode 100644 index 0000000000..9ee6bbef55 --- /dev/null +++ b/t/t4018/cpp-c++-function @@ -0,0 +1,4 @@ +Item RIGHT::DoSomething( Args with_spaces ) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-class-constructor b/t/t4018/cpp-class-constructor new file mode 100644 index 0000000000..ec4f115c25 --- /dev/null +++ b/t/t4018/cpp-class-constructor @@ -0,0 +1,4 @@ +Item::Item(int RIGHT) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-class-constructor-mem-init b/t/t4018/cpp-class-constructor-mem-init new file mode 100644 index 0000000000..49a69f37e1 --- /dev/null +++ b/t/t4018/cpp-class-constructor-mem-init @@ -0,0 +1,5 @@ +Item::Item(int RIGHT) : + member(0) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-class-definition b/t/t4018/cpp-class-definition new file mode 100644 index 0000000000..11b61da3b7 --- /dev/null +++ b/t/t4018/cpp-class-definition @@ -0,0 +1,4 @@ +class RIGHT +{ + int ChangeMe; +}; diff --git a/t/t4018/cpp-class-definition-derived b/t/t4018/cpp-class-definition-derived new file mode 100644 index 0000000000..3b98cd09ab --- /dev/null +++ b/t/t4018/cpp-class-definition-derived @@ -0,0 +1,5 @@ +class RIGHT : + public Baseclass +{ + int ChangeMe; +}; diff --git a/t/t4018/cpp-class-destructor b/t/t4018/cpp-class-destructor new file mode 100644 index 0000000000..5487665096 --- /dev/null +++ b/t/t4018/cpp-class-destructor @@ -0,0 +1,4 @@ +RIGHT::~RIGHT() +{ + ChangeMe; +} diff --git a/t/t4018/cpp-function-returning-global-type b/t/t4018/cpp-function-returning-global-type new file mode 100644 index 0000000000..1084d5990e --- /dev/null +++ b/t/t4018/cpp-function-returning-global-type @@ -0,0 +1,4 @@ +::Item get::it::RIGHT() +{ + ChangeMe; +} diff --git a/t/t4018/cpp-function-returning-nested b/t/t4018/cpp-function-returning-nested new file mode 100644 index 0000000000..d9750aa61a --- /dev/null +++ b/t/t4018/cpp-function-returning-nested @@ -0,0 +1,5 @@ +get::Item get::it::RIGHT() +{ + ChangeMe; +} + diff --git a/t/t4018/cpp-function-returning-pointer b/t/t4018/cpp-function-returning-pointer new file mode 100644 index 0000000000..ef15657ea8 --- /dev/null +++ b/t/t4018/cpp-function-returning-pointer @@ -0,0 +1,4 @@ +const char *get_it_RIGHT(char *ptr) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-function-returning-reference b/t/t4018/cpp-function-returning-reference new file mode 100644 index 0000000000..01b051df70 --- /dev/null +++ b/t/t4018/cpp-function-returning-reference @@ -0,0 +1,4 @@ +string& get::it::RIGHT(char *ptr) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-gnu-style-function b/t/t4018/cpp-gnu-style-function new file mode 100644 index 0000000000..08c7c7565a --- /dev/null +++ b/t/t4018/cpp-gnu-style-function @@ -0,0 +1,5 @@ +const char * +RIGHT(int arg) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-namespace-definition b/t/t4018/cpp-namespace-definition new file mode 100644 index 0000000000..6749980241 --- /dev/null +++ b/t/t4018/cpp-namespace-definition @@ -0,0 +1,4 @@ +namespace RIGHT +{ + ChangeMe; +} diff --git a/t/t4018/cpp-operator-definition b/t/t4018/cpp-operator-definition new file mode 100644 index 0000000000..1acd827159 --- /dev/null +++ b/t/t4018/cpp-operator-definition @@ -0,0 +1,4 @@ +Value operator+(Value LEFT, Value RIGHT) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-skip-access-specifiers b/t/t4018/cpp-skip-access-specifiers new file mode 100644 index 0000000000..4d4a9dbb9d --- /dev/null +++ b/t/t4018/cpp-skip-access-specifiers @@ -0,0 +1,8 @@ +class RIGHT : public Baseclass +{ +public: +protected: +private: + void DoSomething(); + int ChangeMe; +}; diff --git a/t/t4018/cpp-skip-comment-block b/t/t4018/cpp-skip-comment-block new file mode 100644 index 0000000000..3800b9967a --- /dev/null +++ b/t/t4018/cpp-skip-comment-block @@ -0,0 +1,9 @@ +struct item RIGHT(int i) +// Do not +// pick up +/* these +** comments. +*/ +{ + ChangeMe; +} diff --git a/t/t4018/cpp-skip-labels b/t/t4018/cpp-skip-labels new file mode 100644 index 0000000000..b9c10aba22 --- /dev/null +++ b/t/t4018/cpp-skip-labels @@ -0,0 +1,8 @@ +void RIGHT (void) +{ +repeat: // C++ comment +next: /* C comment */ + do_something(); + + ChangeMe; +} diff --git a/t/t4018/cpp-struct-definition b/t/t4018/cpp-struct-definition new file mode 100644 index 0000000000..521c59fd15 --- /dev/null +++ b/t/t4018/cpp-struct-definition @@ -0,0 +1,9 @@ +struct RIGHT { + unsigned + /* this bit field looks like a label and should not be picked up */ + decoy_bitfield: 2, + more : 1; + int filler; + + int ChangeMe; +}; diff --git a/t/t4018/cpp-struct-single-line b/t/t4018/cpp-struct-single-line new file mode 100644 index 0000000000..a0de5fb800 --- /dev/null +++ b/t/t4018/cpp-struct-single-line @@ -0,0 +1,7 @@ +void wrong() +{ +} + +struct RIGHT_iterator_tag {}; + +int ChangeMe; diff --git a/t/t4018/cpp-template-function-definition b/t/t4018/cpp-template-function-definition new file mode 100644 index 0000000000..0cdf5ba5bd --- /dev/null +++ b/t/t4018/cpp-template-function-definition @@ -0,0 +1,4 @@ +template int RIGHT(T arg) +{ + ChangeMe; +} diff --git a/t/t4018/cpp-union-definition b/t/t4018/cpp-union-definition new file mode 100644 index 0000000000..7ec94df697 --- /dev/null +++ b/t/t4018/cpp-union-definition @@ -0,0 +1,4 @@ +union RIGHT { + double v; + int ChangeMe; +}; diff --git a/t/t4018/cpp-void-c-function b/t/t4018/cpp-void-c-function new file mode 100644 index 0000000000..153081e872 --- /dev/null +++ b/t/t4018/cpp-void-c-function @@ -0,0 +1,4 @@ +void RIGHT (void) +{ + ChangeMe; +} diff --git a/t/t4018/custom1-pattern b/t/t4018/custom1-pattern new file mode 100644 index 0000000000..e8fd59f884 --- /dev/null +++ b/t/t4018/custom1-pattern @@ -0,0 +1,17 @@ +public class Beer +{ + int special, RIGHT; + public static void main(String args[]) + { + String s=" "; + for(int x = 99; x > 0; x--) + { + System.out.print(x + " bottles of beer on the wall " + + x + " bottles of beer\n" // ChangeMe + + "Take one down, pass it around, " + (x - 1) + + " bottles of beer on the wall.\n"); + } + System.out.print("Go to the store, buy some more,\n" + + "99 bottles of beer on the wall.\n"); + } +} diff --git a/t/t4018/custom2-match-to-end-of-line b/t/t4018/custom2-match-to-end-of-line new file mode 100644 index 0000000000..f88ac318b7 --- /dev/null +++ b/t/t4018/custom2-match-to-end-of-line @@ -0,0 +1,8 @@ +public class RIGHT_Beer +{ + int special; + public static void main(String args[]) + { + System.out.print("ChangeMe"); + } +} diff --git a/t/t4018/custom3-alternation-in-pattern b/t/t4018/custom3-alternation-in-pattern new file mode 100644 index 0000000000..5f3769c64f --- /dev/null +++ b/t/t4018/custom3-alternation-in-pattern @@ -0,0 +1,17 @@ +public class Beer +{ + int special; + public static void main(String RIGHT[]) + { + String s=" "; + for(int x = 99; x > 0; x--) + { + System.out.print(x + " bottles of beer on the wall " + + x + " bottles of beer\n" // ChangeMe + + "Take one down, pass it around, " + (x - 1) + + " bottles of beer on the wall.\n"); + } + System.out.print("Go to the store, buy some more,\n" + + "99 bottles of beer on the wall.\n"); + } +} diff --git a/t/t4018/java-class-member-function b/t/t4018/java-class-member-function new file mode 100644 index 0000000000..298bc7a71b --- /dev/null +++ b/t/t4018/java-class-member-function @@ -0,0 +1,8 @@ +public class Beer +{ + int special; + public static void main(String RIGHT[]) + { + System.out.print("ChangeMe"); + } +} diff --git a/t/t4018/perl-skip-end-of-heredoc b/t/t4018/perl-skip-end-of-heredoc new file mode 100644 index 0000000000..c22d39b256 --- /dev/null +++ b/t/t4018/perl-skip-end-of-heredoc @@ -0,0 +1,8 @@ +sub RIGHTwithheredocument { + print <<"EOF" +decoy here-doc +EOF + # some lines of context + # to pad it out + print "ChangeMe\n"; +} diff --git a/t/t4018/perl-skip-forward-decl b/t/t4018/perl-skip-forward-decl new file mode 100644 index 0000000000..a98cb8bdad --- /dev/null +++ b/t/t4018/perl-skip-forward-decl @@ -0,0 +1,10 @@ +package RIGHT; + +use strict; +use warnings; +use parent qw(Exporter); +our @EXPORT_OK = qw(round finalround); + +sub other; # forward declaration + +# ChangeMe diff --git a/t/t4018/perl-skip-sub-in-pod b/t/t4018/perl-skip-sub-in-pod new file mode 100644 index 0000000000..e39f02462e --- /dev/null +++ b/t/t4018/perl-skip-sub-in-pod @@ -0,0 +1,18 @@ +=head1 NAME + +Beer - subroutine to output fragment of a drinking song + +=head1 SYNOPSIS_RIGHT + + use Beer qw(round finalround); + + sub song { + for (my $i = 99; $i > 0; $i--) { + round $i; + } + finalround; + } + + ChangeMe; + +=cut diff --git a/t/t4018/perl-sub-definition b/t/t4018/perl-sub-definition new file mode 100644 index 0000000000..a507d1f645 --- /dev/null +++ b/t/t4018/perl-sub-definition @@ -0,0 +1,4 @@ +sub RIGHT { + my ($n) = @_; + print "ChangeMe"; +} diff --git a/t/t4018/perl-sub-definition-kr-brace b/t/t4018/perl-sub-definition-kr-brace new file mode 100644 index 0000000000..330b3df114 --- /dev/null +++ b/t/t4018/perl-sub-definition-kr-brace @@ -0,0 +1,4 @@ +sub RIGHT +{ + print "ChangeMe\n"; +} diff --git a/t/t4209-log-pickaxe.sh b/t/t4209-log-pickaxe.sh index 38fb80f643..844df760f7 100755 --- a/t/t4209-log-pickaxe.sh +++ b/t/t4209-log-pickaxe.sh @@ -3,82 +3,72 @@ test_description='log --grep/--author/--regexp-ignore-case/-S/-G' . ./test-lib.sh +test_log () { + expect=$1 + kind=$2 + needle=$3 + shift 3 + rest=$@ + + case $kind in + --*) + opt=$kind=$needle + ;; + *) + opt=$kind$needle + ;; + esac + case $expect in + expect_nomatch) + match=nomatch + ;; + *) + match=match + ;; + esac + + test_expect_success "log $kind${rest:+ $rest} ($match)" " + git log $rest $opt --format=%H >actual && + test_cmp $expect actual + " +} + +# test -i and --regexp-ignore-case and expect both to behave the same way +test_log_icase () { + test_log $@ --regexp-ignore-case + test_log $@ -i +} + test_expect_success setup ' + >expect_nomatch && + >file && git add file && test_tick && git commit -m initial && + git rev-parse --verify HEAD >expect_initial && echo Picked >file && + git add file && test_tick && - git commit -a --author="Another Person " -m second -' - -test_expect_success 'log --grep' ' - git log --grep=initial --format=%H >actual && - git rev-parse --verify HEAD^ >expect && - test_cmp expect actual -' - -test_expect_success 'log --grep --regexp-ignore-case' ' - git log --regexp-ignore-case --grep=InItial --format=%H >actual && - git rev-parse --verify HEAD^ >expect && - test_cmp expect actual -' - -test_expect_success 'log --grep -i' ' - git log -i --grep=InItial --format=%H >actual && - git rev-parse --verify HEAD^ >expect && - test_cmp expect actual -' - -test_expect_success 'log --author --regexp-ignore-case' ' - git log --regexp-ignore-case --author=person --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' - -test_expect_success 'log --author -i' ' - git log -i --author=person --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' - -test_expect_success 'log -G (nomatch)' ' - git log -Gpicked --format=%H >actual && - >expect && - test_cmp expect actual -' - -test_expect_success 'log -G (match)' ' - git log -GPicked --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' - -test_expect_success 'log -G --regexp-ignore-case (nomatch)' ' - git log --regexp-ignore-case -Gpickle --format=%H >actual && - >expect && - test_cmp expect actual + git commit --author="Another Person " -m second && + git rev-parse --verify HEAD >expect_second ' -test_expect_success 'log -G -i (nomatch)' ' - git log -i -Gpickle --format=%H >actual && - >expect && - test_cmp expect actual -' +test_log expect_initial --grep initial +test_log expect_nomatch --grep InItial +test_log_icase expect_initial --grep InItial +test_log_icase expect_nomatch --grep initail -test_expect_success 'log -G --regexp-ignore-case (match)' ' - git log --regexp-ignore-case -Gpicked --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' +test_log expect_second --author Person +test_log expect_nomatch --author person +test_log_icase expect_second --author person +test_log_icase expect_nomatch --author spreon -test_expect_success 'log -G -i (match)' ' - git log -i -Gpicked --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' +test_log expect_nomatch -G picked +test_log expect_second -G Picked +test_log_icase expect_nomatch -G pickle +test_log_icase expect_second -G picked test_expect_success 'log -G --textconv (missing textconv tool)' ' echo "* diff=test" >.gitattributes && @@ -89,46 +79,19 @@ test_expect_success 'log -G --textconv (missing textconv tool)' ' test_expect_success 'log -G --no-textconv (missing textconv tool)' ' echo "* diff=test" >.gitattributes && git -c diff.test.textconv=missing log -Gfoo --no-textconv >actual && - >expect && - test_cmp expect actual && + test_cmp expect_nomatch actual && rm .gitattributes ' -test_expect_success 'log -S (nomatch)' ' - git log -Spicked --format=%H >actual && - >expect && - test_cmp expect actual -' - -test_expect_success 'log -S (match)' ' - git log -SPicked --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' - -test_expect_success 'log -S --regexp-ignore-case (match)' ' - git log --regexp-ignore-case -Spicked --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' - -test_expect_success 'log -S -i (match)' ' - git log -i -Spicked --format=%H >actual && - git rev-parse --verify HEAD >expect && - test_cmp expect actual -' - -test_expect_success 'log -S --regexp-ignore-case (nomatch)' ' - git log --regexp-ignore-case -Spickle --format=%H >actual && - >expect && - test_cmp expect actual -' +test_log expect_nomatch -S picked +test_log expect_second -S Picked +test_log_icase expect_second -S picked +test_log_icase expect_nomatch -S pickle -test_expect_success 'log -S -i (nomatch)' ' - git log -i -Spickle --format=%H >actual && - >expect && - test_cmp expect actual -' +test_log expect_nomatch -S p.cked --pickaxe-regex +test_log expect_second -S P.cked --pickaxe-regex +test_log_icase expect_second -S p.cked --pickaxe-regex +test_log_icase expect_nomatch -S p.ckle --pickaxe-regex test_expect_success 'log -S --textconv (missing textconv tool)' ' echo "* diff=test" >.gitattributes && @@ -139,8 +102,7 @@ test_expect_success 'log -S --textconv (missing textconv tool)' ' test_expect_success 'log -S --no-textconv (missing textconv tool)' ' echo "* diff=test" >.gitattributes && git -c diff.test.textconv=missing log -Sfoo --no-textconv >actual && - >expect && - test_cmp expect actual && + test_cmp expect_nomatch actual && rm .gitattributes ' diff --git a/t/t5305-include-tag.sh b/t/t5305-include-tag.sh index b061864a87..21517c70cd 100755 --- a/t/t5305-include-tag.sh +++ b/t/t5305-include-tag.sh @@ -45,9 +45,7 @@ test_expect_success 'unpack objects' ' test_expect_success 'check unpacked result (have commit, no tag)' ' git rev-list --objects $commit >list.expect && ( - GIT_DIR=clone.git && - export GIT_DIR && - test_must_fail git cat-file -e $tag && + test_must_fail env GIT_DIR=clone.git git cat-file -e $tag && git rev-list --objects $commit ) >list.actual && test_cmp list.expect list.actual diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index d3a3afaba8..f13525caa3 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -91,7 +91,10 @@ test_expect_success 'fetch (partial bitmap)' ' test_expect_success 'incremental repack cannot create bitmaps' ' test_commit more-1 && - test_must_fail git repack -d + find .git/objects/pack -name "*.bitmap" >expect && + git repack -d && + find .git/objects/pack -name "*.bitmap" >actual && + test_cmp expect actual ' test_expect_success 'incremental repack can disable bitmaps' ' diff --git a/t/t5602-clone-remote-exec.sh b/t/t5602-clone-remote-exec.sh index 3f353d99e8..cbcceab9d5 100755 --- a/t/t5602-clone-remote-exec.sh +++ b/t/t5602-clone-remote-exec.sh @@ -12,21 +12,14 @@ test_expect_success setup ' ' test_expect_success 'clone calls git upload-pack unqualified with no -u option' ' - ( - GIT_SSH=./not_ssh && - export GIT_SSH && - test_must_fail git clone localhost:/path/to/repo junk - ) && + test_must_fail env GIT_SSH=./not_ssh git clone localhost:/path/to/repo junk && echo "localhost git-upload-pack '\''/path/to/repo'\''" >expected && test_cmp expected not_ssh_output ' test_expect_success 'clone calls specified git upload-pack with -u option' ' - ( - GIT_SSH=./not_ssh && - export GIT_SSH && - test_must_fail git clone -u ./something/bin/git-upload-pack localhost:/path/to/repo junk - ) && + test_must_fail env GIT_SSH=./not_ssh \ + git clone -u ./something/bin/git-upload-pack localhost:/path/to/repo junk && echo "localhost ./something/bin/git-upload-pack '\''/path/to/repo'\''" >expected && test_cmp expected not_ssh_output ' diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh index c4903687fb..3c087e907c 100755 --- a/t/t5701-clone-local.sh +++ b/t/t5701-clone-local.sh @@ -12,8 +12,8 @@ test_expect_success 'preparing origin repository' ' : >file && git add . && git commit -m1 && git clone --bare . a.git && git clone --bare . x && - test "$(GIT_CONFIG=a.git/config git config --bool core.bare)" = true && - test "$(GIT_CONFIG=x/config git config --bool core.bare)" = true && + test "$(cd a.git && git config --bool core.bare)" = true && + test "$(cd x && git config --bool core.bare)" = true && git bundle create b1.bundle --all && git bundle create b2.bundle master && mkdir dir && @@ -24,7 +24,7 @@ test_expect_success 'preparing origin repository' ' test_expect_success 'local clone without .git suffix' ' git clone -l -s a b && (cd b && - test "$(GIT_CONFIG=.git/config git config --bool core.bare)" = false && + test "$(git config --bool core.bare)" = false && git fetch) ' diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index c33cc25805..25fd2e7f46 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -231,10 +231,8 @@ test_expect_success 'proper failure checks for fetching' ' ' test_expect_success 'proper failure checks for pushing' ' - (GIT_REMOTE_TESTGIT_FAILURE=1 && - export GIT_REMOTE_TESTGIT_FAILURE && - cd local && - test_must_fail git push --all + (cd local && + test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git push --all ) ' diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 98744038ec..9d9d9de08e 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -190,12 +190,9 @@ test_expect_success '%C(auto) respects --no-color' ' ' test_expect_success TTY '%C(auto) respects --color=auto (stdout is tty)' ' - ( - TERM=vt100 && export TERM && - test_terminal \ - git log --format=$AUTO_COLOR -1 --color=auto >actual && - has_color actual - ) + test_terminal env TERM=vt100 \ + git log --format=$AUTO_COLOR -1 --color=auto >actual && + has_color actual ' test_expect_success '%C(auto) respects --color=auto (stdout not tty)' ' diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index b9365b431d..da958a8b56 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -146,11 +146,7 @@ test_expect_success 'no color when stdout is a regular file' ' test_expect_success TTY 'color when writing to a pager' ' rm -f paginated.out && test_config color.ui auto && - ( - TERM=vt100 && - export TERM && - test_terminal git log - ) && + test_terminal env TERM=vt100 git log && colorful paginated.out ' @@ -158,11 +154,7 @@ test_expect_success TTY 'colors are suppressed by color.pager' ' rm -f paginated.out && test_config color.ui auto && test_config color.pager false && - ( - TERM=vt100 && - export TERM && - test_terminal git log - ) && + test_terminal env TERM=vt100 git log && ! colorful paginated.out ' @@ -181,11 +173,7 @@ test_expect_success 'color when writing to a file intended for a pager' ' test_expect_success TTY 'colors are sent to pager for external commands' ' test_config alias.externallog "!git log" && test_config color.ui auto && - ( - TERM=vt100 && - export TERM && - test_terminal git -p externallog - ) && + test_terminal env TERM=vt100 git -p externallog && colorful paginated.out ' diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index c28e8d8ada..7c88245031 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -249,8 +249,7 @@ test_expect_success 'submodule add in subdirectory with relative path should fai ' test_expect_success 'setup - add an example entry to .gitmodules' ' - GIT_CONFIG=.gitmodules \ - git config submodule.example.url git://example.com/init.git + git config --file=.gitmodules submodule.example.url git://example.com/init.git ' test_expect_success 'status should fail for unmapped paths' ' @@ -264,7 +263,7 @@ test_expect_success 'setup - map path in .gitmodules' ' path = init EOF - GIT_CONFIG=.gitmodules git config submodule.example.path init && + git config --file=.gitmodules submodule.example.path init && test_cmp expect .gitmodules ' diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 28ca76384f..29d3d2cca0 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -63,9 +63,6 @@ test_expect_success 'setup a submodule tree' ' git submodule add ../none none && test_tick && git commit -m "none" - ) && - (cd super && - git tag initial-setup ) ' @@ -706,7 +703,7 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re git clone super_update_r super_update_r2 && (cd super_update_r2 && git submodule update --init --recursive >actual && - test_i18ngrep "Submodule path .submodule/subsubmodule.: .git reset --hard -q" actual && + test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual && (cd submodule/subsubmodule && git log > ../../expected ) && @@ -777,38 +774,4 @@ test_expect_success 'submodule update --recursive drops module name before recur test_i18ngrep "Submodule path .deeper/submodule/subsubmodule.: checked out" actual ) ' - -test_expect_success 'submodule update --checkout clones detached HEAD' ' - git clone super super4 && - echo "detached HEAD" >expected && - (cd super4 && - git reset --hard initial-setup && - git submodule init submodule && - git submodule update >> /tmp/log 2>&1 && - (cd submodule && - git symbolic-ref HEAD > ../../actual || - echo "detached HEAD" > ../../actual - ) - ) && - test_cmp actual expected && - rm -rf super4 -' - -test_expect_success 'submodule update --merge clones attached HEAD' ' - git clone super super4 && - echo "refs/heads/master" >expected && - (cd super4 && - git reset --hard initial-setup && - git submodule init submodule && - git config submodule.submodule.update merge && - git submodule update --merge && - (cd submodule && - git symbolic-ref HEAD > ../../actual || - echo "detached HEAD" > ../../actual - ) - ) && - test_cmp actual expected && - rm -rf super4 -' - test_done diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh index 357375151d..03dce09cfe 100755 --- a/t/t7505-prepare-commit-msg-hook.sh +++ b/t/t7505-prepare-commit-msg-hook.sh @@ -134,14 +134,26 @@ test_expect_success 'with hook (-c)' ' test_expect_success 'with hook (merge)' ' - head=`git rev-parse HEAD` && - git checkout -b other HEAD@{1} && - echo "more" >> file && + test_when_finished "git checkout -f master" && + git checkout -B other HEAD@{1} && + echo "more" >>file && + git add file && + git commit -m other && + git checkout - && + git merge --no-ff other && + test "`git log -1 --pretty=format:%s`" = "merge (no editor)" +' + +test_expect_success 'with hook and editor (merge)' ' + + test_when_finished "git checkout -f master" && + git checkout -B other HEAD@{1} && + echo "more" >>file && git add file && git commit -m other && git checkout - && - git merge other && - test "`git log -1 --pretty=format:%s`" = merge + env GIT_EDITOR="\"\$FAKE_EDITOR\"" git merge --no-ff -e other && + test "`git log -1 --pretty=format:%s`" = "merge" ' cat > "$HOOK" <<'EOF' @@ -151,34 +163,37 @@ EOF test_expect_success 'with failing hook' ' + test_when_finished "git checkout -f master" && head=`git rev-parse HEAD` && echo "more" >> file && git add file && - ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head + test_must_fail env GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head ' test_expect_success 'with failing hook (--no-verify)' ' + test_when_finished "git checkout -f master" && head=`git rev-parse HEAD` && echo "more" >> file && git add file && - ! GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head + test_must_fail env GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head ' test_expect_success 'with failing hook (merge)' ' + test_when_finished "git checkout -f master" && git checkout -B other HEAD@{1} && echo "more" >> file && git add file && rm -f "$HOOK" && git commit -m other && - write_script "$HOOK" <<-EOF + write_script "$HOOK" <<-EOF && exit 1 EOF git checkout - && - test_must_fail git merge other + test_must_fail git merge --no-ff other ' diff --git a/t/t7514-commit-patch.sh b/t/t7514-commit-patch.sh new file mode 100755 index 0000000000..998a2103c7 --- /dev/null +++ b/t/t7514-commit-patch.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +test_description='hunk edit with "commit -p -m"' +. ./test-lib.sh + +if ! test_have_prereq PERL +then + skip_all="skipping '$test_description' tests, perl not available" + test_done +fi + +test_expect_success 'setup (initial)' ' + echo line1 >file && + git add file && + git commit -m commit1 +' + +test_expect_success 'edit hunk "commit -p -m message"' ' + test_when_finished "rm -f editor_was_started" && + rm -f editor_was_started && + echo more >>file && + echo e | env GIT_EDITOR=": >editor_was_started" git commit -p -m commit2 file && + test -r editor_was_started +' + +test_expect_success 'edit hunk "commit --dry-run -p -m message"' ' + test_when_finished "rm -f editor_was_started" && + rm -f editor_was_started && + echo more >>file && + echo e | env GIT_EDITOR=": >editor_was_started" git commit -p -m commit3 file && + test -r editor_was_started +' + +test_done diff --git a/t/t9130-git-svn-authors-file.sh b/t/t9130-git-svn-authors-file.sh index c3443ceb25..c44de267a1 100755 --- a/t/t9130-git-svn-authors-file.sh +++ b/t/t9130-git-svn-authors-file.sh @@ -67,7 +67,7 @@ test_expect_success 'fetch fails on ee' ' ' tmp_config_get () { - GIT_CONFIG=.git/svn/.metadata git config --get "$1" + git config --file=.git/svn/.metadata --get "$1" } test_expect_success 'failure happened without negative side effects' ' @@ -97,7 +97,6 @@ test_expect_success 'fresh clone with svn.authors-file in config' ' test x = x"$(git config svn.authorsfile)" && test_config="$HOME"/.gitconfig && sane_unset GIT_DIR && - sane_unset GIT_CONFIG && git config --global \ svn.authorsfile "$HOME"/svn-authors && test x"$HOME"/svn-authors = x"$(git config svn.authorsfile)" && diff --git a/t/t9154-git-svn-fancy-glob.sh b/t/t9154-git-svn-fancy-glob.sh index b780e0efe3..a0150f057d 100755 --- a/t/t9154-git-svn-fancy-glob.sh +++ b/t/t9154-git-svn-fancy-glob.sh @@ -22,7 +22,7 @@ test_expect_success 'add red branch' " " test_expect_success 'add gre branch' " - GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev && + git config --file=.git/svn/.metadata --unset svn-remote.svn.branches-maxRev && git config svn-remote.svn.branches 'branches/{red,gre}:refs/remotes/*' && git svn fetch && git rev-parse refs/remotes/red && @@ -31,7 +31,7 @@ test_expect_success 'add gre branch' " " test_expect_success 'add green branch' " - GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev && + git config --file=.git/svn/.metadata --unset svn-remote.svn.branches-maxRev && git config svn-remote.svn.branches 'branches/{red,green}:refs/remotes/*' && git svn fetch && git rev-parse refs/remotes/red && @@ -40,7 +40,7 @@ test_expect_success 'add green branch' " " test_expect_success 'add all branches' " - GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev && + git config --file=.git/svn/.metadata --unset svn-remote.svn.branches-maxRev && git config svn-remote.svn.branches 'branches/*:refs/remotes/*' && git svn fetch && git rev-parse refs/remotes/red && diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 3edc4086d8..ed98e64477 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -25,7 +25,6 @@ perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { test_done } -unset GIT_DIR GIT_CONFIG WORKDIR=$(pwd) SERVERDIR=$(pwd)/gitcvs.git git_config="$SERVERDIR/config" diff --git a/t/test-lib.sh b/t/test-lib.sh index 87f327ff8b..c081668dfe 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -655,7 +655,6 @@ else # normal case, use ../bin-wrappers only unless $with_dashes: fi fi GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt -unset GIT_CONFIG GIT_CONFIG_NOSYSTEM=1 GIT_ATTR_NOSYSTEM=1 export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM diff --git a/userdiff.c b/userdiff.c index 10b61ec37d..fad52d6392 100644 --- a/userdiff.c +++ b/userdiff.c @@ -125,15 +125,13 @@ PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$", "\\\\[a-zA-Z@]+|\\\\.|[a-zA-Z0-9\x80-\xff]+"), PATTERNS("cpp", /* Jump targets or access declarations */ - "!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:.*$\n" - /* C/++ functions/methods at top level */ - "^([A-Za-z_][A-Za-z_0-9]*([ \t*]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n" - /* compound type at top level */ - "^((struct|class|enum)[^;]*)$", + "!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:[[:space:]]*($|/[/*])\n" + /* functions/methods, variables, and compounds at top level */ + "^((::[[:space:]]*)?[A-Za-z_].*)$", /* -- */ "[a-zA-Z_][a-zA-Z0-9_]*" - "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?" - "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"), + "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lLuU]*" + "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->\\*?|\\.\\*"), PATTERNS("csharp", /* Keywords */ "!^[ \t]*(do|while|for|if|else|instanceof|new|return|switch|case|throw|catch|using)\n" diff --git a/wt-status.c b/wt-status.c index e1827faf07..ec7344e508 100644 --- a/wt-status.c +++ b/wt-status.c @@ -1547,19 +1547,21 @@ static void wt_shortstatus_print_tracking(struct wt_status *s) return; } +#define LABEL(string) (s->no_gettext ? (string) : _(string)) + color_fprintf(s->fp, header_color, " ["); if (upstream_is_gone) { - color_fprintf(s->fp, header_color, _("gone")); + color_fprintf(s->fp, header_color, LABEL(N_("gone"))); } else if (!num_ours) { - color_fprintf(s->fp, header_color, _("behind ")); + color_fprintf(s->fp, header_color, LABEL(N_("behind "))); color_fprintf(s->fp, branch_color_remote, "%d", num_theirs); } else if (!num_theirs) { - color_fprintf(s->fp, header_color, _("ahead ")); + color_fprintf(s->fp, header_color, LABEL(N_(("ahead ")))); color_fprintf(s->fp, branch_color_local, "%d", num_ours); } else { - color_fprintf(s->fp, header_color, _("ahead ")); + color_fprintf(s->fp, header_color, LABEL(N_(("ahead ")))); color_fprintf(s->fp, branch_color_local, "%d", num_ours); - color_fprintf(s->fp, header_color, _(", behind ")); + color_fprintf(s->fp, header_color, ", %s", LABEL(N_("behind "))); color_fprintf(s->fp, branch_color_remote, "%d", num_theirs); } @@ -1604,5 +1606,6 @@ void wt_porcelain_print(struct wt_status *s) s->use_color = 0; s->relative_paths = 0; s->prefix = NULL; + s->no_gettext = 1; wt_shortstatus_print(s); } diff --git a/wt-status.h b/wt-status.h index b56ce3f035..283a9fef03 100644 --- a/wt-status.h +++ b/wt-status.h @@ -50,6 +50,7 @@ struct wt_status { enum commit_whence whence; int nowarn; int use_color; + int no_gettext; int display_comment_prefix; int relative_paths; int submodule_summary;