Merge branch 'ib/rev-parse-parseopt-argh'
authorJunio C Hamano <gitster@pobox.com>
Mon, 31 Mar 2014 23:30:59 +0000 (16:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 31 Mar 2014 23:30:59 +0000 (16:30 -0700)
Teaches the "rev-parse --parseopt" mechanism used by scripted
Porcelains to parse command line options and give help text how to
supply argv-help (the placeholder string for an option parameter,
e.g. "key-id" in "--gpg-sign=<key-id>").

* ib/rev-parse-parseopt-argh:
t1502: protect runs of SPs used in the indentation
rev-parse --parseopt: option argument name hints

86 files changed:
Documentation/RelNotes/2.0.0.txt
Documentation/config.txt
Documentation/git-am.txt
Documentation/git-commit.txt
Documentation/git-status.txt
Documentation/gitk.txt
Documentation/merge-strategies.txt
Makefile
builtin/add.c
builtin/cat-file.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/gc.c
builtin/index-pack.c
builtin/merge.c
builtin/mv.c
builtin/pack-objects.c
commit.h
configure.ac
connect.c
contrib/subtree/git-subtree.sh
diff-no-index.c
entry.c
fsck.c
git-rebase--interactive.sh
git-rebase.sh
revision.c
run-command.c
run-command.h
t/lib-terminal.sh
t/t1300-repo-config.sh
t/t1510-repo-setup.sh
t/t3200-branch.sh
t/t3301-notes.sh
t/t3400-rebase.sh
t/t3404-rebase-interactive.sh
t/t3413-rebase-hook.sh
t/t4014-format-patch.sh
t/t4018-diff-funcname.sh
t/t4018/README [new file with mode: 0644]
t/t4018/cpp-c++-function [new file with mode: 0644]
t/t4018/cpp-class-constructor [new file with mode: 0644]
t/t4018/cpp-class-constructor-mem-init [new file with mode: 0644]
t/t4018/cpp-class-definition [new file with mode: 0644]
t/t4018/cpp-class-definition-derived [new file with mode: 0644]
t/t4018/cpp-class-destructor [new file with mode: 0644]
t/t4018/cpp-function-returning-global-type [new file with mode: 0644]
t/t4018/cpp-function-returning-nested [new file with mode: 0644]
t/t4018/cpp-function-returning-pointer [new file with mode: 0644]
t/t4018/cpp-function-returning-reference [new file with mode: 0644]
t/t4018/cpp-gnu-style-function [new file with mode: 0644]
t/t4018/cpp-namespace-definition [new file with mode: 0644]
t/t4018/cpp-operator-definition [new file with mode: 0644]
t/t4018/cpp-skip-access-specifiers [new file with mode: 0644]
t/t4018/cpp-skip-comment-block [new file with mode: 0644]
t/t4018/cpp-skip-labels [new file with mode: 0644]
t/t4018/cpp-struct-definition [new file with mode: 0644]
t/t4018/cpp-struct-single-line [new file with mode: 0644]
t/t4018/cpp-template-function-definition [new file with mode: 0644]
t/t4018/cpp-union-definition [new file with mode: 0644]
t/t4018/cpp-void-c-function [new file with mode: 0644]
t/t4018/custom1-pattern [new file with mode: 0644]
t/t4018/custom2-match-to-end-of-line [new file with mode: 0644]
t/t4018/custom3-alternation-in-pattern [new file with mode: 0644]
t/t4018/java-class-member-function [new file with mode: 0644]
t/t4018/perl-skip-end-of-heredoc [new file with mode: 0644]
t/t4018/perl-skip-forward-decl [new file with mode: 0644]
t/t4018/perl-skip-sub-in-pod [new file with mode: 0644]
t/t4018/perl-sub-definition [new file with mode: 0644]
t/t4018/perl-sub-definition-kr-brace [new file with mode: 0644]
t/t5305-include-tag.sh
t/t5310-pack-bitmaps.sh
t/t5510-fetch.sh
t/t5602-clone-remote-exec.sh
t/t5801-remote-helpers.sh
t/t6006-rev-list-format.sh
t/t7001-mv.sh
t/t7006-pager.sh
t/t7502-commit.sh
t/t7505-prepare-commit-msg-hook.sh
t/t7514-commit-patch.sh [new file with mode: 0755]
t/test-lib.sh
userdiff.c
wt-status.c
wt-status.h
index 5dc11f405f81d45df452dbb2400ffd00506f58d2..98ec2103cd3c3d461bf641a3ff57c384d75d4fbb 100644 (file)
@@ -47,6 +47,11 @@ Updates since v1.9 series
 
 UI, Workflows & Features
 
+ * "git rebase" learned to interpret a lone "-" as "@{-1}", the
+   branch that we were previously on.
+
+ * "git commit --cleanup=<mode>" learned a new mode, scissors.
+
  * "git tag --list" output can be sorted using "version sort" with
    "--sort=version:refname".
 
@@ -153,6 +158,57 @@ 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 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.
+   (merge fb8a4e8 jk/mv-submodules-fix later to maint).
+
+ * Length limit for the pathname used when removing a path in a deep
+   subdirectory has been removed to avoid buffer overflows.
+   (merge 2f29e0c mh/remove-subtree-long-pathname-fix later to maint).
+
+ * The test helper lib-terminal always run an actual test_expect_*
+   when included, which screwed up with the use of skil-all that may
+   have to be done later.
+   (merge 7e27173 jk/lib-terminal-lazy later to maint).
+
+ * "git index-pack" used a wrong variable to name the keep-file in an
+   error message when the file cannot be written or closed.
+   (merge de983a0 nd/index-pack-error-message later to maint).
+
+ * "rebase -i" produced a broken insn sheet when the title of a commit
+   happened to contain '\n' (or ended with '\c') due to a careless use
+   of 'echo'.
+   (merge cb1aefd us/printf-not-echo later to maint).
+
+ * There were a few instances of 'git-foo' remaining in the
+   documentation that should have been spelled 'git foo'.
+   (merge 3c3e6f5 rr/doc-merge-strategies later to maint).
+
  * Serving objects from a shallow repository needs to write a
    new file to hold the temporary shallow boundaries but it was not
    cleaned when we exit due to die() or a signal.
index 73c8973aae5bfad789a998e5623fc219959edaf6..c415aadbbcd8b6b99f21687e1038867a0d2bf0cf 100644 (file)
@@ -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
index a2b97582fe010ffcab70db30e006a7a94d6b767b..9adce372ec6e6ec0d371c411da1e5002baea5f51 100644 (file)
@@ -14,7 +14,7 @@ SYNOPSIS
         [--ignore-date] [--ignore-space-change | --ignore-whitespace]
         [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
         [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
-        [--[no-]scissors] [-S[<keyid>]]
+        [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
         [(<mbox> | <Maildir>)...]
 'git am' (--continue | --skip | --abort)
 
@@ -97,6 +97,12 @@ default.   You can use `--no-utf8` to override this.
        program that applies
        the patch.
 
+--patch-format::
+       By default the command will try to detect the patch format
+       automatically. This option allows the user to bypass the automatic
+       detection and specify the patch format that the patch(es) should be
+       interpreted as. Valid formats are mbox, stgit, stgit-series and hg.
+
 -i::
 --interactive::
        Run interactively.
index 7c42e9cabcb250b93cd286e8efe23df90ea0f71c..429267abf640ef42b5bf9361ed8ab78f6509f77f 100644 (file)
@@ -176,7 +176,7 @@ OPTIONS
 --cleanup=<mode>::
        This option determines how the supplied commit message should be
        cleaned up before committing.  The '<mode>' can be `strip`,
-       `whitespace`, `verbatim`, or `default`.
+       `whitespace`, `verbatim`, `scissors` or `default`.
 +
 --
 strip::
@@ -186,6 +186,12 @@ whitespace::
        Same as `strip` except #commentary is not removed.
 verbatim::
        Do not change the message at all.
+scissors::
+       Same as `whitespace`, except that everything from (and
+       including) the line
+       "`# ------------------------ >8 ------------------------`"
+       is truncated if the message is to be edited. "`#`" can be
+       customized with core.commentChar.
 default::
        Same as `strip` if the message is to be edited.
        Otherwise `whitespace`.
index a4acaa038cd4255c91df1a03c16c6a396f0c1219..def635f57879c467d85f43d44aafac90c7f72a9a 100644 (file)
@@ -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.
index 1e9e38ae40e8396af82c2d6f47d3e8e8508a921d..7e03fcc62d1a388552cdd1e92f75183c0278cf28 100644 (file)
@@ -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
 -------
index 350949810e224c9963278cbc73351011448e9b56..7bbd19b30032ca76966cbcf44a0b5b738c8f5ced 100644 (file)
@@ -1,10 +1,10 @@
 MERGE STRATEGIES
 ----------------
 
-The merge mechanism ('git-merge' and 'git-pull' commands) allows the
+The merge mechanism (`git merge` and `git pull` commands) allows the
 backend 'merge strategies' to be chosen with `-s` option.  Some strategies
 can also take their own options, which can be passed by giving `-X<option>`
-arguments to 'git-merge' and/or 'git-pull'.
+arguments to `git merge` and/or `git pull`.
 
 resolve::
        This can only resolve two heads (i.e. the current branch
index 36463919afd6ee40c3a0487e481ebbaadce7b6d8..c5316a34ac4e176967ae824fccabaf4c12561ae9 100644 (file)
--- 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.
index 4b045bace12c1fa951785dc09c05a46b09cd9fc7..459208a326cd4cebfa813168d81a06c27fc54fc5 100644 (file)
@@ -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] [--] <pathspec>..."),
@@ -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;
 }
 
index d5a93e0e911ccbe4560a03ed78436bfb174e0f68..707330499fad66a0bddbb5cf96ff0569e2fe3433 100644 (file)
@@ -269,6 +269,8 @@ static int batch_objects(struct batch_options *opt)
 {
        struct strbuf buf = STRBUF_INIT;
        struct expand_data data;
+       int save_warning;
+       int retval = 0;
 
        if (!opt->format)
                opt->format = "%(objectname) %(objecttype) %(objectsize)";
@@ -297,11 +299,10 @@ static int batch_objects(struct batch_options *opt)
         * warn) ends up dwarfing the actual cost of the object lookups
         * themselves. We can work around it by just turning off the warning.
         */
+       save_warning = warn_on_object_refname_ambiguity;
        warn_on_object_refname_ambiguity = 0;
 
        while (strbuf_getline(&buf, stdin, '\n') != EOF) {
-               int error;
-
                if (data.split_on_whitespace) {
                        /*
                         * Split at first whitespace, tying off the beginning
@@ -316,12 +317,14 @@ static int batch_objects(struct batch_options *opt)
                        data.rest = p;
                }
 
-               error = batch_one_object(buf.buf, opt, &data);
-               if (error)
-                       return error;
+               retval = batch_one_object(buf.buf, opt, &data);
+               if (retval)
+                       break;
        }
 
-       return 0;
+       strbuf_release(&buf);
+       warn_on_object_refname_ambiguity = save_warning;
+       return retval;
 }
 
 static const char * const cat_file_usage[] = {
index ada51fa70ff59b10fd79168a4377d923638591e9..1b86d9c868c35c7f0ad3f4b39f9d225c8365c77c 100644 (file)
@@ -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. */
 
index 43e772ccdbaba3172f7ee1a969f92b300cb9d5a1..9b3c04d914b3d318f723c2d3ded403fca9503c07 100644 (file)
@@ -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);
index 3783bcadcd5232ceccab7f4fd2559a9999c53ffa..d9550c54d02bbd1ba4df87734433dea4a7097e2e 100644 (file)
@@ -113,6 +113,7 @@ static char *sign_commit;
 static enum {
        CLEANUP_SPACE,
        CLEANUP_NONE,
+       CLEANUP_SCISSORS,
        CLEANUP_ALL
 } cleanup_mode;
 static const char *cleanup_arg;
@@ -610,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) {
@@ -755,7 +756,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                int ident_shown = 0;
                int saved_color_setting;
                char *ai_tmp, *ci_tmp;
-               if (whence != FROM_COMMIT)
+               if (whence != FROM_COMMIT) {
+                       if (cleanup_mode == CLEANUP_SCISSORS)
+                               wt_status_add_cut_line(s->fp);
                        status_printf_ln(s, GIT_COLOR_NORMAL,
                            whence == FROM_MERGE
                                ? _("\n"
@@ -771,6 +774,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                                git_path(whence == FROM_MERGE
                                         ? "MERGE_HEAD"
                                         : "CHERRY_PICK_HEAD"));
+               }
 
                fprintf(s->fp, "\n");
                if (cleanup_mode == CLEANUP_ALL)
@@ -778,6 +782,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                                _("Please enter the commit message for your changes."
                                  " Lines starting\nwith '%c' will be ignored, and an empty"
                                  " message aborts the commit.\n"), comment_line_char);
+               else if (cleanup_mode == CLEANUP_SCISSORS && whence == FROM_COMMIT)
+                       wt_status_add_cut_line(s->fp);
                else /* CLEANUP_SPACE, that is. */
                        status_printf(s, GIT_COLOR_NORMAL,
                                _("Please enter the commit message for your changes."
@@ -867,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) {
@@ -884,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;
        }
 
@@ -1068,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)
@@ -1133,6 +1137,8 @@ static int parse_and_validate_options(int argc, const char *argv[],
                cleanup_mode = CLEANUP_SPACE;
        else if (!strcmp(cleanup_arg, "strip"))
                cleanup_mode = CLEANUP_ALL;
+       else if (!strcmp(cleanup_arg, "scissors"))
+               cleanup_mode = use_editor ? CLEANUP_SCISSORS : CLEANUP_SPACE;
        else
                die(_("Invalid cleanup mode %s"), cleanup_arg);
 
@@ -1450,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;
@@ -1605,8 +1634,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                die(_("could not read commit message: %s"), strerror(saved_errno));
        }
 
-       /* Truncate the message just before the diff, if any. */
-       if (verbose)
+       if (verbose || /* Truncate the message just before the diff, if any. */
+           cleanup_mode == CLEANUP_SCISSORS)
                wt_status_truncate_message_at_cut_line(&sb);
 
        if (cleanup_mode != CLEANUP_NONE)
@@ -1674,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");
index 63d400bcb2092b1751427994b35057f72b04de17..11cf295515a25b1df19af7a14c2cd03911d957b5 100644 (file)
@@ -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;
 }
index a6b1c17996da28cef97560378e7586bbf1bd8b6b..b9f6e12c0e91635eafd8510dc7cf20d6c3e58433 100644 (file)
@@ -1291,7 +1291,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
                if (keep_fd < 0) {
                        if (errno != EEXIST)
                                die_errno(_("cannot write keep file '%s'"),
-                                         keep_name);
+                                         keep_name ? keep_name : name);
                } else {
                        if (keep_msg_len > 0) {
                                write_or_die(keep_fd, keep_msg, keep_msg_len);
@@ -1299,7 +1299,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
                        }
                        if (close(keep_fd) != 0)
                                die_errno(_("cannot close written keep file '%s'"),
-                                   keep_name);
+                                         keep_name ? keep_name : name);
                        report = "keep";
                }
        }
index f0cf1205faa66c5ae8b4603f04239f1efbd999d6..e15d0e145a51d52687619673aec3ee80c0485375 100644 (file)
@@ -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))
index 7e26eb5229a0c8a526314cecb9860c3dfb0fed00..2a7243f52e413c821f9f75969edcc0a9822c8e21 100644 (file)
@@ -180,6 +180,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                                modes = xrealloc(modes,
                                                                (argc + last - first)
                                                                * sizeof(enum update_mode));
+                                               submodule_gitfile = xrealloc(submodule_gitfile,
+                                                               (argc + last - first)
+                                                               * sizeof(char *));
                                        }
 
                                        dst = add_slash(dst);
@@ -193,6 +196,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                                        prefix_path(dst, dst_len,
                                                                path + length + 1);
                                                modes[argc + j] = INDEX;
+                                               submodule_gitfile[argc + j] = NULL;
                                        }
                                        argc += last - first;
                                }
@@ -228,6 +232,11 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                        memmove(destination + i,
                                                destination + i + 1,
                                                (argc - i) * sizeof(char *));
+                                       memmove(modes + i, modes + i + 1,
+                                               (argc - i) * sizeof(enum update_mode));
+                                       memmove(submodule_gitfile + i,
+                                               submodule_gitfile + i + 1,
+                                               (argc - i) * sizeof(char *));
                                        i--;
                                }
                        } else
index 0ee5f1ff94e1689b099f04fff8a05728c70f2f4f..7950c4342f81544f719b20add2e1233be36fc718 100644 (file)
@@ -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);
index 55631f191f2a01276e8a16192117fb3cf25bc958..a9f177ba488a7002409eb2cdee1f7e9c3673529f 100644 (file)
--- 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 */
index 24ab7383aecf36e010f838d04b671903d1d8a79f..b7112542b4b62fbbf0235c923f75803edc149e5c 100644 (file)
@@ -890,7 +890,7 @@ GIT_CONF_SUBST([HAVE_STRINGS_H])
 # and libcharset does
 CHARSET_LIB=
 AC_CHECK_LIB([iconv], [locale_charset],
-       [],
+       [CHARSET_LIB=-liconv],
        [AC_CHECK_LIB([charset], [locale_charset],
                      [CHARSET_LIB=-lcharset])])
 GIT_CONF_SUBST([CHARSET_LIB])
index 4150412e2c0ebf6129137baf41c9d268d50c60bd..a983d061a90f0b720afa1a9b50247da299164d79 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -727,7 +727,7 @@ struct child_process *git_connect(int fd[2], const char *url,
                                *arg++ = port;
                        }
                        *arg++ = ssh_host;
-               }       else {
+               } else {
                        /* remove repo-local variables from the environment */
                        conn->env = local_repo_env;
                        conn->use_shell = 1;
index dc59a91031ea6815456e5c86f5494bf56858c0d1..db925ca76991c635ea53fe7f38d6608d08dfc4d5 100755 (executable)
@@ -46,6 +46,7 @@ ignore_joins=
 annotate=
 squash=
 message=
+prefix=
 
 debug()
 {
index 8e10bff30e5269687e67866c2d3c66d62e3bb883..c554691df0bdb46eee26b4ca4c957fa86fc9f8c4 100644 (file)
@@ -15,8 +15,9 @@
 #include "log-tree.h"
 #include "builtin.h"
 #include "string-list.h"
+#include "dir.h"
 
-static int read_directory(const char *path, struct string_list *list)
+static int read_directory_contents(const char *path, struct string_list *list)
 {
        DIR *dir;
        struct dirent *e;
@@ -25,7 +26,7 @@ static int read_directory(const char *path, struct string_list *list)
                return error("Could not open directory %s", path);
 
        while ((e = readdir(dir)))
-               if (strcmp(".", e->d_name) && strcmp("..", e->d_name))
+               if (!is_dot_or_dotdot(e->d_name))
                        string_list_insert(list, e->d_name);
 
        closedir(dir);
@@ -107,9 +108,9 @@ static int queue_diff(struct diff_options *o,
                int i1, i2, ret = 0;
                size_t len1 = 0, len2 = 0;
 
-               if (name1 && read_directory(name1, &p1))
+               if (name1 && read_directory_contents(name1, &p1))
                        return -1;
-               if (name2 && read_directory(name2, &p2)) {
+               if (name2 && read_directory_contents(name2, &p2)) {
                        string_list_clear(&p1, 0);
                        return -1;
                }
diff --git a/entry.c b/entry.c
index 7b7aa8167adade20f38cfb2709e02b3ed31f11a4..77c688262477e783b4bcbc237ef281eecab0661d 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -44,33 +44,33 @@ static void create_directories(const char *path, int path_len,
        free(buf);
 }
 
-static void remove_subtree(const char *path)
+static void remove_subtree(struct strbuf *path)
 {
-       DIR *dir = opendir(path);
+       DIR *dir = opendir(path->buf);
        struct dirent *de;
-       char pathbuf[PATH_MAX];
-       char *name;
+       int origlen = path->len;
 
        if (!dir)
-               die_errno("cannot opendir '%s'", path);
-       strcpy(pathbuf, path);
-       name = pathbuf + strlen(path);
-       *name++ = '/';
+               die_errno("cannot opendir '%s'", path->buf);
        while ((de = readdir(dir)) != NULL) {
                struct stat st;
+
                if (is_dot_or_dotdot(de->d_name))
                        continue;
-               strcpy(name, de->d_name);
-               if (lstat(pathbuf, &st))
-                       die_errno("cannot lstat '%s'", pathbuf);
+
+               strbuf_addch(path, '/');
+               strbuf_addstr(path, de->d_name);
+               if (lstat(path->buf, &st))
+                       die_errno("cannot lstat '%s'", path->buf);
                if (S_ISDIR(st.st_mode))
-                       remove_subtree(pathbuf);
-               else if (unlink(pathbuf))
-                       die_errno("cannot unlink '%s'", pathbuf);
+                       remove_subtree(path);
+               else if (unlink(path->buf))
+                       die_errno("cannot unlink '%s'", path->buf);
+               strbuf_setlen(path, origlen);
        }
        closedir(dir);
-       if (rmdir(path))
-               die_errno("cannot rmdir '%s'", path);
+       if (rmdir(path->buf))
+               die_errno("cannot rmdir '%s'", path->buf);
 }
 
 static int create_file(const char *path, unsigned int mode)
@@ -245,27 +245,25 @@ static int check_path(const char *path, int len, struct stat *st, int skiplen)
 int checkout_entry(struct cache_entry *ce,
                   const struct checkout *state, char *topath)
 {
-       static struct strbuf path_buf = STRBUF_INIT;
-       char *path;
+       static struct strbuf path = STRBUF_INIT;
        struct stat st;
-       int len;
 
        if (topath)
                return write_entry(ce, topath, state, 1);
 
-       strbuf_reset(&path_buf);
-       strbuf_add(&path_buf, state->base_dir, state->base_dir_len);
-       strbuf_add(&path_buf, ce->name, ce_namelen(ce));
-       path = path_buf.buf;
-       len = path_buf.len;
+       strbuf_reset(&path);
+       strbuf_add(&path, state->base_dir, state->base_dir_len);
+       strbuf_add(&path, ce->name, ce_namelen(ce));
 
-       if (!check_path(pathlen, &st, state->base_dir_len)) {
+       if (!check_path(path.buf, path.len, &st, state->base_dir_len)) {
                unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
                if (!changed)
                        return 0;
                if (!state->force) {
                        if (!state->quiet)
-                               fprintf(stderr, "%s already exists, no checkout\n", path);
+                               fprintf(stderr,
+                                       "%s already exists, no checkout\n",
+                                       path.buf);
                        return -1;
                }
 
@@ -280,12 +278,14 @@ int checkout_entry(struct cache_entry *ce,
                        if (S_ISGITLINK(ce->ce_mode))
                                return 0;
                        if (!state->force)
-                               return error("%s is a directory", path);
-                       remove_subtree(path);
-               } else if (unlink(path))
-                       return error("unable to unlink old '%s' (%s)", path, strerror(errno));
+                               return error("%s is a directory", path.buf);
+                       remove_subtree(&path);
+               } else if (unlink(path.buf))
+                       return error("unable to unlink old '%s' (%s)",
+                                    path.buf, strerror(errno));
        } else if (state->not_new)
                return 0;
-       create_directories(path, len, state);
-       return write_entry(ce, path, state, 0);
+
+       create_directories(path.buf, path.len, state);
+       return write_entry(ce, path.buf, state, 0);
 }
diff --git a/fsck.c b/fsck.c
index 64bf279fd7e42da1921a65d725007c52c7ddc5fb..abed62bac77c67e7c7447a18fea75f228406baac 100644 (file)
--- 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;
index a1adae83131b5918ec6f994043f3f3ccd3b8c3d8..1c41cbd66c77641772c41898362b7fc550c4faca 100644 (file)
@@ -749,7 +749,7 @@ rearrange_squash () {
                                        ;;
                                esac
                        done
-                       echo "$sha1 $action $prefix $rest"
+                       printf '%s %s %s %s\n' "$sha1" "$action" "$prefix" "$rest"
                        # if it's a single word, try to resolve to a full sha1 and
                        # emit a second copy. This allows us to match on both message
                        # and on sha1 prefix
index 5f6732bf3dce78966da1cbb83d4094d584f92598..2c75e9fa0f8d4c10e6caa2b3f4d018a11bbf0f8f 100755 (executable)
@@ -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
index 78b5c3ac0b2d7d436b35a69a3cf6c1b023c96dd5..85085501f66b02a9cff9b404f34c0925270cea7f 100644 (file)
@@ -1575,6 +1575,10 @@ static void read_revisions_from_stdin(struct rev_info *revs,
 {
        struct strbuf sb;
        int seen_dashdash = 0;
+       int save_warning;
+
+       save_warning = warn_on_object_refname_ambiguity;
+       warn_on_object_refname_ambiguity = 0;
 
        strbuf_init(&sb, 1000);
        while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
@@ -1596,7 +1600,9 @@ static void read_revisions_from_stdin(struct rev_info *revs,
        }
        if (seen_dashdash)
                read_pathspec_from_stdin(revs, &sb, prune);
+
        strbuf_release(&sb);
+       warn_on_object_refname_ambiguity = save_warning;
 }
 
 static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
index 3914d9c5117f29651b56772da143f0a226494a62..75abc478c6da75471e5fdbb55c74efdfcf3ad160 100644 (file)
@@ -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;
+}
index 6b985afd07a5b58ecadad8859ae90b3430ccb4c2..3653bfa6e123ca8497571a2ca1c47200c1b544a2 100644 (file)
@@ -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 */
index 9a2dca506a8d6c15f52e6ded3aa22a0f08f507a1..51845491bb42ee72a1f7ec33c504e65c5bf8b248 100644 (file)
@@ -1,6 +1,20 @@
 # Helpers for terminal output tests.
 
-test_expect_success PERL 'set up terminal for tests' '
+# Catch tests which should depend on TTY but forgot to. There's no need
+# to aditionally check that the TTY prereq is set here.  If the test declared
+# it and we are running the test, then it must have been set.
+test_terminal () {
+       if ! test_declared_prereq TTY
+       then
+               echo >&4 "test_terminal: need to declare TTY prerequisite"
+               return 127
+       fi
+       perl "$TEST_DIRECTORY"/test-terminal.perl "$@"
+}
+
+test_lazy_prereq TTY '
+       test_have_prereq PERL &&
+
        # Reading from the pty master seems to get stuck _sometimes_
        # on Mac OS X 10.5.0, using Perl 5.10.0 or 5.8.9.
        #
@@ -15,21 +29,8 @@ test_expect_success PERL 'set up terminal for tests' '
        # After 2000 iterations or so it hangs.
        # https://rt.cpan.org/Ticket/Display.html?id=65692
        #
-       if test "$(uname -s)" = Darwin
-       then
-               :
-       elif
-               perl "$TEST_DIRECTORY"/test-terminal.perl \
-                       sh -c "test -t 1 && test -t 2"
-       then
-               test_set_prereq TTY &&
-               test_terminal () {
-                       if ! test_declared_prereq TTY
-                       then
-                               echo >&4 "test_terminal: need to declare TTY prerequisite"
-                               return 127
-                       fi
-                       perl "$TEST_DIRECTORY"/test-terminal.perl "$@"
-               }
-       fi
+       test "$(uname -s)" != Darwin &&
+
+       perl "$TEST_DIRECTORY"/test-terminal.perl \
+               sh -c "test -t 1 && test -t 2"
 '
index c9c426c273e556302338f7a30fc46de64b856eb2..3e3f77b59b797bf1f3f1e0eff7c608ac6ab5b6dd 100755 (executable)
@@ -974,24 +974,15 @@ test_expect_success SYMLINKS 'symlinked configuration' '
 '
 
 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 env GIT_CONFIG=doesnotexist git config --list &&
+       test_must_fail env GIT_CONFIG=doesnotexist git config 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 env GIT_CONFIG=linktonada git config --list &&
+       test_must_fail env GIT_CONFIG=linktolinktonada git config --list
 '
 
 test_expect_success 'check split_cmdline return' "
index cf2ee7885ac9c2172deccc27dfb994546593e842..e1b2a99f105f8700e72974428c126ea049247194 100755 (executable)
@@ -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
 '
index 83037b1cd94046ea1ec82819b7d30790b28634d2..ac31b711f29139470308d9062fea33259cf004ab 100755 (executable)
@@ -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' '
index 3bb79a47af5e2f619753c61436ec577ec025a8ae..cfd67ff3dfc64b160bbc53318df3eb661970f2e1 100755 (executable)
@@ -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
 '
 
index 6d94b1fcd94e9f724c93a389c50066c92c46e1b9..80e0a951ea3b699dc57530c1749a2e727ec6779d 100755 (executable)
@@ -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 &&
index 50e22b1cadff4252dfb552a4db930f49544952aa..c0023a5b4ff6ef60f5d77e9e54a64adf387bce6e 100755 (executable)
@@ -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
 '
 
index 098b75507bf2ef6906f3f4fd4c532bb4c55ce7bd..b6833e9a5fead6d2b47ce8a3d517f64cba6a1514 100755 (executable)
@@ -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)
 '
index 73194b2c3dbe267b759bfd036367366b4955f0c4..9c8063314688ec0c03d3fb2099379cbbf4ff2e19 100755 (executable)
@@ -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
 '
index 38a092a0dadbe09b903484c1d34e240a9d819c77..34591c23da82230f2412b46620f0d3a12188656f 100755 (executable)
@@ -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.java >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.perl >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 <<here document' '
-       test_expect_funcname "sub withheredocument {\$" perl
-'
-
-test_expect_success 'perl pattern is not distracted by sub within POD' '
-       test_expect_funcname "=head" perl
-'
-
-test_expect_success 'perl pattern gets full line of POD header' '
-       test_expect_funcname "=head1 SYNOPSIS\$" perl
-'
-
-test_expect_success 'perl pattern is not distracted by forward declaration' '
-       test_expect_funcname "package Beer;\$" perl
-'
-
-test_expect_success 'custom pattern' '
-       test_config diff.java.funcname "!static
-!String
-[^     ].*s.*" &&
-       test_expect_funcname "int special;\$"
-'
-
 test_expect_success 'last regexp must not be negated' '
+       echo "*.java diff=java" >.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 (file)
index 0000000..283e01c
--- /dev/null
@@ -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 (file)
index 0000000..9ee6bbe
--- /dev/null
@@ -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 (file)
index 0000000..ec4f115
--- /dev/null
@@ -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 (file)
index 0000000..49a69f3
--- /dev/null
@@ -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 (file)
index 0000000..11b61da
--- /dev/null
@@ -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 (file)
index 0000000..3b98cd0
--- /dev/null
@@ -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 (file)
index 0000000..5487665
--- /dev/null
@@ -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 (file)
index 0000000..1084d59
--- /dev/null
@@ -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 (file)
index 0000000..d9750aa
--- /dev/null
@@ -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 (file)
index 0000000..ef15657
--- /dev/null
@@ -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 (file)
index 0000000..01b051d
--- /dev/null
@@ -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 (file)
index 0000000..08c7c75
--- /dev/null
@@ -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 (file)
index 0000000..6749980
--- /dev/null
@@ -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 (file)
index 0000000..1acd827
--- /dev/null
@@ -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 (file)
index 0000000..4d4a9db
--- /dev/null
@@ -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 (file)
index 0000000..3800b99
--- /dev/null
@@ -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 (file)
index 0000000..b9c10ab
--- /dev/null
@@ -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 (file)
index 0000000..521c59f
--- /dev/null
@@ -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 (file)
index 0000000..a0de5fb
--- /dev/null
@@ -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 (file)
index 0000000..0cdf5ba
--- /dev/null
@@ -0,0 +1,4 @@
+template<class T> int RIGHT(T arg)
+{
+       ChangeMe;
+}
diff --git a/t/t4018/cpp-union-definition b/t/t4018/cpp-union-definition
new file mode 100644 (file)
index 0000000..7ec94df
--- /dev/null
@@ -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 (file)
index 0000000..153081e
--- /dev/null
@@ -0,0 +1,4 @@
+void RIGHT (void)
+{
+       ChangeMe;
+}
diff --git a/t/t4018/custom1-pattern b/t/t4018/custom1-pattern
new file mode 100644 (file)
index 0000000..e8fd59f
--- /dev/null
@@ -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 (file)
index 0000000..f88ac31
--- /dev/null
@@ -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 (file)
index 0000000..5f3769c
--- /dev/null
@@ -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 (file)
index 0000000..298bc7a
--- /dev/null
@@ -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 (file)
index 0000000..c22d39b
--- /dev/null
@@ -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 (file)
index 0000000..a98cb8b
--- /dev/null
@@ -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 (file)
index 0000000..e39f024
--- /dev/null
@@ -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 (file)
index 0000000..a507d1f
--- /dev/null
@@ -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 (file)
index 0000000..330b3df
--- /dev/null
@@ -0,0 +1,4 @@
+sub RIGHT
+{
+       print "ChangeMe\n";
+}
index b061864a8743636ae7759ff4e8ff2694410617a1..21517c70cd49ab91ab267544311d8c33173e3c3e 100755 (executable)
@@ -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
index d3a3afaba821f8b70c5f365f1046ba7a707e5085..f13525caa309e48ab32f89066a3e9661dfc25e09 100755 (executable)
@@ -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' '
index ab28594c62dd7cddc69d3afdb075b48c34091c45..5acd753dcff6b8a0e908b82dc86295a7727fb4b4 100755 (executable)
@@ -301,7 +301,7 @@ test_expect_success 'fetch via rsync' '
        mkdir rsynced &&
        (cd rsynced &&
         git init --bare &&
-        git fetch "rsync:$(pwd)/../.git" master:refs/heads/master &&
+        git fetch "rsync:../.git" master:refs/heads/master &&
         git gc --prune &&
         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
         git fsck --full)
@@ -312,7 +312,7 @@ test_expect_success 'push via rsync' '
        (cd rsynced2 &&
         git init) &&
        (cd rsynced &&
-        git push "rsync:$(pwd)/../rsynced2/.git" master) &&
+        git push "rsync:../rsynced2/.git" master) &&
        (cd rsynced2 &&
         git gc --prune &&
         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
@@ -323,7 +323,7 @@ test_expect_success 'push via rsync' '
        mkdir rsynced3 &&
        (cd rsynced3 &&
         git init) &&
-       git push --all "rsync:$(pwd)/rsynced3/.git" &&
+       git push --all "rsync:rsynced3/.git" &&
        (cd rsynced3 &&
         test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
         git fsck --full)
index 3f353d99e8f4255b131b4d44d7ec2a2c73140f0f..cbcceab9d56b591ee851374c9030a23a4c65a462 100755 (executable)
@@ -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
 '
index c33cc25805d2a913725355a183118a0dd5547800..25fd2e7f46cb559372125e08671445476cbf6022 100755 (executable)
@@ -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
        )
 '
 
index 98744038eccb396c752e6a4b6ced702733c0d396..9d9d9de08e1926525c24fc01c1217a96964fa1ee 100755 (executable)
@@ -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)' '
index e3c8c2c1b8817acd85866470c6f76c4a4f8d17d7..215d43d6a6c8ce7f2b30e32dce6dfe34adc98b15 100755 (executable)
@@ -294,7 +294,8 @@ test_expect_success 'setup submodule' '
        git submodule add ./. sub &&
        echo content >file &&
        git add file &&
-       git commit -m "added sub and file"
+       git commit -m "added sub and file" &&
+       git branch submodule
 '
 
 test_expect_success 'git mv cannot move a submodule in a file' '
@@ -463,4 +464,14 @@ test_expect_success 'checking out a commit before submodule moved needs manual u
        ! test -s actual
 '
 
+test_expect_success 'mv -k does not accidentally destroy submodules' '
+       git checkout submodule &&
+       mkdir dummy dest &&
+       git mv -k dummy sub dest &&
+       git status --porcelain >actual &&
+       grep "^R  sub -> dest/sub" actual &&
+       git reset --hard &&
+       git checkout .
+'
+
 test_done
index b9365b431d1e412905ddd0efad1f809625224ba9..da958a8b569e6e8ad0c4d2e20b0454a0180155cc 100755 (executable)
@@ -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
 '
 
index 6313da2cdd979c6264e7a255711c6e444b768b96..9a3f3a1b4151ebf16cfd773a0f9efcb1b61d40d7 100755 (executable)
@@ -223,6 +223,22 @@ test_expect_success 'cleanup commit messages (whitespace option,-F)' '
 
 '
 
+test_expect_success 'cleanup commit messages (scissors option,-F,-e)' '
+
+       echo >>negative &&
+       cat >text <<EOF &&
+
+# to be kept
+# ------------------------ >8 ------------------------
+to be removed
+EOF
+       echo "# to be kept" >expect &&
+       git commit --cleanup=scissors -e -F text -a &&
+       git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+       test_cmp expect actual
+
+'
+
 test_expect_success 'cleanup commit messages (strip option,-F)' '
 
        echo >>negative &&
index 357375151d79d03d11275875dd10ceea42a3ba47..03dce09cfea5f1b5c19e7e8c4537a657cdf55dfc 100755 (executable)
@@ -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 (executable)
index 0000000..998a210
--- /dev/null
@@ -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
index 569b52dc0fa32f48f37dc0d29771118cc624c5e7..87f327ff8bcd2c2a29fcbabe74c226232b54f728 100644 (file)
@@ -283,7 +283,7 @@ error "Test script did not set test_description."
 
 if test "$help" = "t"
 then
-       echo "$test_description"
+       printf '%s\n' "$test_description"
        exit 0
 fi
 
@@ -334,7 +334,7 @@ test_failure_ () {
        test_failure=$(($test_failure + 1))
        say_color error "not ok $test_count - $1"
        shift
-       echo "$@" | sed -e 's/^/#       /'
+       printf '%s\n' "$*" | sed -e 's/^/#      /'
        test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
 }
 
index 10b61ec37da035fb864c94a4037960ed30b1248c..fad52d6392fab8aadc8f6555db5aafcde224a120 100644 (file)
@@ -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"
index c89c3bb5373c49490980eba45f5a81707cc79bea..e1827faf073ce384bea6a697dd903ffc643bdfdc 100644 (file)
@@ -17,7 +17,7 @@
 #include "strbuf.h"
 #include "utf8.h"
 
-static char cut_line[] =
+static const char cut_line[] =
 "------------------------ >8 ------------------------\n";
 
 static char default_wt_status_colors[][COLOR_MAXLEN] = {
@@ -841,6 +841,17 @@ void wt_status_truncate_message_at_cut_line(struct strbuf *buf)
        strbuf_release(&pattern);
 }
 
+void wt_status_add_cut_line(FILE *fp)
+{
+       const char *explanation = _("Do not touch the line above.\nEverything below will be removed.");
+       struct strbuf buf = STRBUF_INIT;
+
+       fprintf(fp, "%c %s", comment_line_char, cut_line);
+       strbuf_add_commented_lines(&buf, explanation, strlen(explanation));
+       fputs(buf.buf, fp);
+       strbuf_release(&buf);
+}
+
 static void wt_status_print_verbose(struct wt_status *s)
 {
        struct rev_info rev;
@@ -866,14 +877,8 @@ static void wt_status_print_verbose(struct wt_status *s)
         * diff before committing.
         */
        if (s->fp != stdout) {
-               const char *explanation = _("Do not touch the line above.\nEverything below will be removed.");
-               struct strbuf buf = STRBUF_INIT;
-
                rev.diffopt.use_color = 0;
-               fprintf(s->fp, "%c %s", comment_line_char, cut_line);
-               strbuf_add_commented_lines(&buf, explanation, strlen(explanation));
-               fputs(buf.buf, s->fp);
-               strbuf_release(&buf);
+               wt_status_add_cut_line(s->fp);
        }
        run_diff_index(&rev, 1);
 }
index 30a481258366733ad5d6a65e3a9c3ae1ee74e833..b56ce3f0355f3a1e188c7d9bd44ea90f0d06d76f 100644 (file)
@@ -92,6 +92,7 @@ struct wt_status_state {
 };
 
 void wt_status_truncate_message_at_cut_line(struct strbuf *);
+void wt_status_add_cut_line(FILE *fp);
 void wt_status_prepare(struct wt_status *s);
 void wt_status_print(struct wt_status *s);
 void wt_status_collect(struct wt_status *s);