]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'sb/merge-recursive-code-cleanup' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 10 Jul 2017 20:59:09 +0000 (13:59 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Jul 2017 20:59:09 +0000 (13:59 -0700)
Code clean-up.

* sb/merge-recursive-code-cleanup:
  merge-recursive: use DIFF_XDL_SET macro

42 files changed:
Documentation/gitattributes.txt
Documentation/pretty-formats.txt
alias.c
apply.c
builtin/submodule--helper.c
config.c
contrib/diff-highlight/.gitignore [new file with mode: 0644]
contrib/diff-highlight/DiffHighlight.pm [moved from contrib/diff-highlight/diff-highlight with 91% similarity, mode: 0644]
contrib/diff-highlight/Makefile
contrib/diff-highlight/README
contrib/diff-highlight/diff-highlight.perl [new file with mode: 0644]
contrib/subtree/Makefile
git-add--interactive.perl
git-rebase.sh
git.c
help.c
mergetools/meld
pack-bitmap.c
po/de.po
pretty.c
read-cache.c
sequencer.c
setup.c
sha1dc/sha1.c
strbuf.c
strbuf.h
t/t1300-repo-config.sh
t/t1301-shared-repo.sh
t/t1308-config-set.sh
t/t1450-fsck.sh
t/t1700-split-index.sh
t/t3404-rebase-interactive.sh
t/t3420-rebase-autostash.sh
t/t3701-add-interactive.sh
t/t4005-diff-rename-2.sh
t/t4129-apply-samemode.sh
t/t4133-apply-filenames.sh
t/t4136-apply-check.sh
t/t5534-push-signed.sh
t/t7006-pager.sh
t/t7508-status.sh
t/test-lib-functions.sh

index 4736483865ee56c3cf23f41985e2064fbef0cfea..2a2d7e2a4d2a9cab2af8bd881dd880ca2a52235a 100644 (file)
@@ -229,7 +229,7 @@ From a clean working directory:
 
 -------------------------------------------------
 $ echo "* text=auto" >.gitattributes
-$ rm .git/index     # Remove the index to re-scan the working directory
+$ git read-tree --empty   # Clean index, force re-scan of working directory
 $ git add .
 $ git status        # Show files that will be normalized
 $ git commit -m "Introduce end-of-line normalization"
index a48d267e26c1098e003ed6342b33c6e43d57a884..4d6dac5770bed76cada2f53334e239c70d15a073 100644 (file)
@@ -174,11 +174,12 @@ endif::git-rev-list[]
 - '%Creset': reset color
 - '%C(...)': color specification, as described under Values in the
   "CONFIGURATION FILE" section of linkgit:git-config[1];
-  adding `auto,` at the beginning will emit color only when colors are
-  enabled for log output (by `color.diff`, `color.ui`, or `--color`, and
-  respecting the `auto` settings of the former if we are going to a
-  terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring
-  on the next placeholders until the color is switched again.
+  adding `auto,` at the beginning (e.g. `%C(auto,red)`) will emit
+  color only when colors are enabled for log output (by `color.diff`,
+  `color.ui`, or `--color`, and respecting the `auto` settings of the
+  former if we are going to a terminal). `auto` alone (i.e.
+  `%C(auto)`) will turn on auto coloring on the next placeholders
+  until the color is switched again.
 - '%m': left (`<`), right (`>`) or boundary (`-`) mark
 - '%n': newline
 - '%%': a raw '%'
diff --git a/alias.c b/alias.c
index 3b90397a99d9f7ed4a0c1c5a83f5e69c879e752f..05263046614e10945cb8d81ef3e42e0d5f2c9a2e 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -1,14 +1,28 @@
 #include "cache.h"
 
+struct config_alias_data {
+       const char *alias;
+       char *v;
+};
+
+static int config_alias_cb(const char *key, const char *value, void *d)
+{
+       struct config_alias_data *data = d;
+       const char *p;
+
+       if (skip_prefix(key, "alias.", &p) && !strcmp(p, data->alias))
+               return git_config_string((const char **)&data->v, key, value);
+
+       return 0;
+}
+
 char *alias_lookup(const char *alias)
 {
-       char *v = NULL;
-       struct strbuf key = STRBUF_INIT;
-       strbuf_addf(&key, "alias.%s", alias);
-       if (git_config_key_is_valid(key.buf))
-               git_config_get_string(key.buf, &v);
-       strbuf_release(&key);
-       return v;
+       struct config_alias_data data = { alias, NULL };
+
+       read_early_config(config_alias_cb, &data);
+
+       return data.v;
 }
 
 #define SPLIT_CMDLINE_BAD_ENDING 1
diff --git a/apply.c b/apply.c
index c49cef0637355d33a7a1636fb283210784f14e02..7a9f4c8e0b47437cae25a51b56b08374c55d7255 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -210,6 +210,7 @@ struct patch {
        unsigned ws_rule;
        int lines_added, lines_deleted;
        int score;
+       int extension_linenr; /* first line specifying delete/new/rename/copy */
        unsigned int is_toplevel_relative:1;
        unsigned int inaccurate_eof:1;
        unsigned int is_binary:1;
@@ -1011,20 +1012,27 @@ static int gitdiff_newname(struct apply_state *state,
                                   DIFF_NEW_NAME);
 }
 
+static int parse_mode_line(const char *line, int linenr, unsigned int *mode)
+{
+       char *end;
+       *mode = strtoul(line, &end, 8);
+       if (end == line || !isspace(*end))
+               return error(_("invalid mode on line %d: %s"), linenr, line);
+       return 0;
+}
+
 static int gitdiff_oldmode(struct apply_state *state,
                           const char *line,
                           struct patch *patch)
 {
-       patch->old_mode = strtoul(line, NULL, 8);
-       return 0;
+       return parse_mode_line(line, state->linenr, &patch->old_mode);
 }
 
 static int gitdiff_newmode(struct apply_state *state,
                           const char *line,
                           struct patch *patch)
 {
-       patch->new_mode = strtoul(line, NULL, 8);
-       return 0;
+       return parse_mode_line(line, state->linenr, &patch->new_mode);
 }
 
 static int gitdiff_delete(struct apply_state *state,
@@ -1138,7 +1146,7 @@ static int gitdiff_index(struct apply_state *state,
        memcpy(patch->new_sha1_prefix, line, len);
        patch->new_sha1_prefix[len] = 0;
        if (*ptr == ' ')
-               patch->old_mode = strtoul(ptr+1, NULL, 8);
+               return gitdiff_oldmode(state, ptr + 1, patch);
        return 0;
 }
 
@@ -1322,6 +1330,18 @@ static char *git_header_name(struct apply_state *state,
        }
 }
 
+static int check_header_line(struct apply_state *state, struct patch *patch)
+{
+       int extensions = (patch->is_delete == 1) + (patch->is_new == 1) +
+                        (patch->is_rename == 1) + (patch->is_copy == 1);
+       if (extensions > 1)
+               return error(_("inconsistent header lines %d and %d"),
+                            patch->extension_linenr, state->linenr);
+       if (extensions && !patch->extension_linenr)
+               patch->extension_linenr = state->linenr;
+       return 0;
+}
+
 /* Verify that we recognize the lines following a git header */
 static int parse_git_header(struct apply_state *state,
                            const char *line,
@@ -1388,6 +1408,8 @@ static int parse_git_header(struct apply_state *state,
                        res = p->fn(state, line + oplen, patch);
                        if (res < 0)
                                return -1;
+                       if (check_header_line(state, patch))
+                               return -1;
                        if (res > 0)
                                return offset;
                        break;
@@ -1585,7 +1607,8 @@ static int find_header(struct apply_state *state,
                                patch->old_name = xstrdup(patch->def_name);
                                patch->new_name = xstrdup(patch->def_name);
                        }
-                       if (!patch->is_delete && !patch->new_name) {
+                       if ((!patch->new_name && !patch->is_delete) ||
+                           (!patch->old_name && !patch->is_new)) {
                                error(_("git diff header lacks filename information "
                                             "(line %d)"), state->linenr);
                                return -128;
index 566a5b6a6f8937742e83577918a94f0dcb20c66c..cbb17a90212cb7fadc00b36d16dd770ff93bbef0 100644 (file)
@@ -4,7 +4,6 @@
 #include "quote.h"
 #include "pathspec.h"
 #include "dir.h"
-#include "utf8.h"
 #include "submodule.h"
 #include "submodule-config.h"
 #include "string-list.h"
@@ -326,7 +325,7 @@ static int module_list(int argc, const char **argv, const char *prefix)
                        printf("%06o %s %d\t", ce->ce_mode,
                               oid_to_hex(&ce->oid), ce_stage(ce));
 
-               utf8_fprintf(stdout, "%s\n", ce->name);
+               fprintf(stdout, "%s\n", ce->name);
        }
        return 0;
 }
@@ -1038,7 +1037,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
                return 1;
 
        for_each_string_list_item(item, &suc.projectlines)
-               utf8_fprintf(stdout, "%s", item->string);
+               fprintf(stdout, "%s", item->string);
 
        return 0;
 }
index a30056ec7e9a0cca87dea494a92a4671a19b7643..f0511e58e2af4235201a01618134a020592cf11c 100644 (file)
--- a/config.c
+++ b/config.c
@@ -588,7 +588,8 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
         */
        cf->linenr--;
        ret = fn(name->buf, value, data);
-       cf->linenr++;
+       if (ret >= 0)
+               cf->linenr++;
        return ret;
 }
 
diff --git a/contrib/diff-highlight/.gitignore b/contrib/diff-highlight/.gitignore
new file mode 100644 (file)
index 0000000..c074548
--- /dev/null
@@ -0,0 +1,2 @@
+shebang.perl
+diff-highlight
old mode 100755 (executable)
new mode 100644 (file)
similarity index 91%
rename from contrib/diff-highlight/diff-highlight
rename to contrib/diff-highlight/DiffHighlight.pm
index 81bd804..663992e
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+package DiffHighlight;
 
 use 5.008;
 use warnings FATAL => 'all';
@@ -29,13 +29,14 @@ my @removed;
 my @added;
 my $in_hunk;
 
-# Some scripts may not realize that SIGPIPE is being ignored when launching the
-# pager--for instance scripts written in Python.
-$SIG{PIPE} = 'DEFAULT';
+our $line_cb = sub { print @_ };
+our $flush_cb = sub { local $| = 1 };
+
+sub handle_line {
+       local $_ = shift;
 
-while (<>) {
        if (!$in_hunk) {
-               print;
+               $line_cb->($_);
                $in_hunk = /^$GRAPH*$COLOR*\@\@ /;
        }
        elsif (/^$GRAPH*$COLOR*-/) {
@@ -49,7 +50,7 @@ while (<>) {
                @removed = ();
                @added = ();
 
-               print;
+               $line_cb->($_);
                $in_hunk = /^$GRAPH*$COLOR*[\@ ]/;
        }
 
@@ -62,15 +63,22 @@ while (<>) {
        # place to flush. Flushing on a blank line is a heuristic that
        # happens to match git-log output.
        if (!length) {
-               local $| = 1;
+               $flush_cb->();
        }
 }
 
-# Flush any queued hunk (this can happen when there is no trailing context in
-# the final diff of the input).
-show_hunk(\@removed, \@added);
+sub flush {
+       # Flush any queued hunk (this can happen when there is no trailing
+       # context in the final diff of the input).
+       show_hunk(\@removed, \@added);
+}
 
-exit 0;
+sub highlight_stdin {
+       while (<STDIN>) {
+               handle_line($_);
+       }
+       flush();
+}
 
 # Ideally we would feed the default as a human-readable color to
 # git-config as the fallback value. But diff-highlight does
@@ -88,7 +96,7 @@ sub show_hunk {
 
        # If one side is empty, then there is nothing to compare or highlight.
        if (!@$a || !@$b) {
-               print @$a, @$b;
+               $line_cb->(@$a, @$b);
                return;
        }
 
@@ -97,17 +105,17 @@ sub show_hunk {
        # stupid, and only handle multi-line hunks that remove and add the same
        # number of lines.
        if (@$a != @$b) {
-               print @$a, @$b;
+               $line_cb->(@$a, @$b);
                return;
        }
 
        my @queue;
        for (my $i = 0; $i < @$a; $i++) {
                my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]);
-               print $rm;
+               $line_cb->($rm);
                push @queue, $add;
        }
-       print @queue;
+       $line_cb->(@queue);
 }
 
 sub highlight_pair {
index 9018724524ab7868bb015696e301396f1f9b5667..fbf5c582496eece56b29a91a2f3085716f4b0e9f 100644 (file)
@@ -1,5 +1,20 @@
-# nothing to build
-all:
+all: diff-highlight
 
-test:
+PERL_PATH = /usr/bin/perl
+-include ../../config.mak
+
+PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
+
+diff-highlight: shebang.perl DiffHighlight.pm diff-highlight.perl
+       cat $^ >$@+
+       chmod +x $@+
+       mv $@+ $@
+
+shebang.perl: FORCE
+       @echo '#!$(PERL_PATH_SQ)' >$@+
+       @cmp $@+ $@ >/dev/null 2>/dev/null || mv $@+ $@
+
+test: all
        $(MAKE) -C t
+
+.PHONY: FORCE
index 836b97a73075a51ef8bc66ba080085a7de4c8f32..d4c23431752063c7b455d429321264a4bd6becf7 100644 (file)
@@ -99,6 +99,36 @@ newHighlight = "black #aaffaa"
 ---------------------------------------------
 
 
+Using diff-highlight as a module
+--------------------------------
+
+If you want to pre- or post- process the highlighted lines as part of
+another perl script, you can use the DiffHighlight module. You can
+either "require" it or just cat the module together with your script (to
+avoid run-time dependencies).
+
+Your script may set up one or more of the following variables:
+
+  - $DiffHighlight::line_cb - this should point to a function which is
+    called whenever DiffHighlight has lines (which may contain
+    highlights) to output. The default function prints each line to
+    stdout. Note that the function may be called with multiple lines.
+
+  - $DiffHighlight::flush_cb - this should point to a function which
+    flushes the output (because DiffHighlight believes it has completed
+    processing a logical chunk of input). The default function flushes
+    stdout.
+
+The script may then feed lines, one at a time, to DiffHighlight::handle_line().
+When lines are done processing, they will be fed to $line_cb. Note that
+DiffHighlight may queue up many input lines (to analyze a whole hunk)
+before calling $line_cb. After providing all lines, call
+DiffHighlight::flush() to flush any unprocessed lines.
+
+If you just want to process stdin, DiffHighlight::highlight_stdin()
+is a convenience helper which will loop and flush for you.
+
+
 Bugs
 ----
 
diff --git a/contrib/diff-highlight/diff-highlight.perl b/contrib/diff-highlight/diff-highlight.perl
new file mode 100644 (file)
index 0000000..9b3e9c1
--- /dev/null
@@ -0,0 +1,8 @@
+package main;
+
+# Some scripts may not realize that SIGPIPE is being ignored when launching the
+# pager--for instance scripts written in Python.
+$SIG{PIPE} = 'DEFAULT';
+
+DiffHighlight::highlight_stdin();
+exit 0;
index 6afa9aafdf3b85b44e69aac419d0cd611bb48017..5c6cc4ab2c270acda160df7a5997266d0076d504 100644 (file)
@@ -19,15 +19,27 @@ htmldir ?= $(prefix)/share/doc/git-doc
 INSTALL  ?= install
 RM       ?= rm -f
 
-ASCIIDOC = asciidoc
-XMLTO    = xmlto
+ASCIIDOC         = asciidoc
+ASCIIDOC_CONF    = -f ../../Documentation/asciidoc.conf
+ASCIIDOC_HTML    = xhtml11
+ASCIIDOC_DOCBOOK = docbook
+ASCIIDOC_EXTRA   =
+XMLTO            = xmlto
+
+ifdef USE_ASCIIDOCTOR
+ASCIIDOC         = asciidoctor
+ASCIIDOC_CONF    =
+ASCIIDOC_HTML    = xhtml5
+ASCIIDOC_DOCBOOK = docbook45
+ASCIIDOC_EXTRA  += -I../../Documentation -rasciidoctor-extensions
+ASCIIDOC_EXTRA  += -alitdd='&\#x2d;&\#x2d;'
+endif
 
 ifndef SHELL_PATH
        SHELL_PATH = /bin/sh
 endif
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
 
-ASCIIDOC_CONF = ../../Documentation/asciidoc.conf
 MANPAGE_XSL   = ../../Documentation/manpage-normal.xsl
 
 GIT_SUBTREE_SH := git-subtree.sh
@@ -65,12 +77,12 @@ $(GIT_SUBTREE_DOC): $(GIT_SUBTREE_XML)
        $(XMLTO) -m $(MANPAGE_XSL) man $^
 
 $(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT)
-       $(ASCIIDOC) -b docbook -d manpage -f $(ASCIIDOC_CONF) \
-               -agit_version=$(GIT_VERSION) $^
+       $(ASCIIDOC) -b $(ASCIIDOC_DOCBOOK) -d manpage $(ASCIIDOC_CONF) \
+               -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^
 
 $(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT)
-       $(ASCIIDOC) -b xhtml11 -d manpage -f $(ASCIIDOC_CONF) \
-               -agit_version=$(GIT_VERSION) $^
+       $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage $(ASCIIDOC_CONF) \
+               -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^
 
 $(GIT_SUBTREE_TEST): $(GIT_SUBTREE)
        cp $< $@
index 709a5f6ce6fbdb2da14084e94ae9df1db1c3d0a6..c55c612455205a045bbcae134fa6eeb2c2a3a5bb 100755 (executable)
@@ -1085,7 +1085,7 @@ EOF2
 
        open $fh, '<', $hunkfile
                or die sprintf(__("failed to open hunk edit file for reading: %s"), $!);
-       my @newtext = grep { !/^$comment_line_char/ } <$fh>;
+       my @newtext = grep { !/^\Q$comment_line_char\E/ } <$fh>;
        close $fh;
        unlink $hunkfile;
 
@@ -1140,6 +1140,7 @@ sub prompt_yesno {
        while (1) {
                print colored $prompt_color, $prompt;
                my $line = prompt_single_character;
+               return undef unless defined $line;
                return 0 if $line =~ /^n/i;
                return 1 if $line =~ /^y/i;
        }
index db1deed8464f0643763ed6e3c5e54221cad8c985..2cf73b88e8e83ca34b9eb319dbc2b0a220139b0f 100755 (executable)
@@ -166,14 +166,14 @@ apply_autostash () {
                stash_sha1=$(cat "$state_dir/autostash")
                if git stash apply $stash_sha1 2>&1 >/dev/null
                then
-                       echo "$(gettext 'Applied autostash.')"
+                       echo "$(gettext 'Applied autostash.')" >&2
                else
                        git stash store -m "autostash" -q $stash_sha1 ||
                        die "$(eval_gettext "Cannot store \$stash_sha1")"
                        gettext 'Applying autostash resulted in conflicts.
 Your changes are safe in the stash.
 You can run "git stash pop" or "git stash drop" at any time.
-'
+' >&2
                fi
        fi
 }
diff --git a/git.c b/git.c
index 8ff44f081d43176474b267de5451f2c2e88089d0..58ef570294da1ffc8fed38609d140833426dd14f 100644 (file)
--- a/git.c
+++ b/git.c
@@ -16,50 +16,6 @@ const char git_more_info_string[] =
           "to read about a specific subcommand or concept.");
 
 static int use_pager = -1;
-static char *orig_cwd;
-static const char *env_names[] = {
-       GIT_DIR_ENVIRONMENT,
-       GIT_WORK_TREE_ENVIRONMENT,
-       GIT_IMPLICIT_WORK_TREE_ENVIRONMENT,
-       GIT_PREFIX_ENVIRONMENT
-};
-static char *orig_env[4];
-static int save_restore_env_balance;
-
-static void save_env_before_alias(void)
-{
-       int i;
-
-       assert(save_restore_env_balance == 0);
-       save_restore_env_balance = 1;
-       orig_cwd = xgetcwd();
-       for (i = 0; i < ARRAY_SIZE(env_names); i++) {
-               orig_env[i] = getenv(env_names[i]);
-               orig_env[i] = xstrdup_or_null(orig_env[i]);
-       }
-}
-
-static void restore_env(int external_alias)
-{
-       int i;
-
-       assert(save_restore_env_balance == 1);
-       save_restore_env_balance = 0;
-       if (!external_alias && orig_cwd && chdir(orig_cwd))
-               die_errno("could not move to %s", orig_cwd);
-       free(orig_cwd);
-       for (i = 0; i < ARRAY_SIZE(env_names); i++) {
-               if (external_alias &&
-                   !strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT))
-                       continue;
-               if (orig_env[i]) {
-                       setenv(env_names[i], orig_env[i], 1);
-                       free(orig_env[i]);
-               } else {
-                       unsetenv(env_names[i]);
-               }
-       }
-}
 
 static void commit_pager_choice(void) {
        switch (use_pager) {
@@ -250,19 +206,18 @@ static int handle_alias(int *argcp, const char ***argv)
        const char **new_argv;
        const char *alias_command;
        char *alias_string;
-       int unused_nongit;
-
-       save_env_before_alias();
-       setup_git_directory_gently(&unused_nongit);
 
        alias_command = (*argv)[0];
        alias_string = alias_lookup(alias_command);
        if (alias_string) {
                if (alias_string[0] == '!') {
                        struct child_process child = CHILD_PROCESS_INIT;
+                       int nongit_ok;
+
+                       /* Aliases expect GIT_PREFIX, GIT_DIR etc to be set */
+                       setup_git_directory_gently(&nongit_ok);
 
                        commit_pager_choice();
-                       restore_env(1);
 
                        child.use_shell = 1;
                        argv_array_push(&child.args, alias_string + 1);
@@ -308,8 +263,6 @@ static int handle_alias(int *argcp, const char ***argv)
                ret = 1;
        }
 
-       restore_env(0);
-
        errno = saved_errno;
 
        return ret;
diff --git a/help.c b/help.c
index db7f3d79a016881639a8c0640451afe35b011e5e..9d2811efdabb55bd8ddd89e76a6d461801f7eced 100644 (file)
--- a/help.c
+++ b/help.c
@@ -289,7 +289,7 @@ const char *help_unknown_cmd(const char *cmd)
        memset(&other_cmds, 0, sizeof(other_cmds));
        memset(&aliases, 0, sizeof(aliases));
 
-       git_config(git_unknown_cmd_config, NULL);
+       read_early_config(git_unknown_cmd_config, NULL);
 
        load_command_list("git-", &main_cmds, &other_cmds);
 
@@ -355,12 +355,18 @@ const char *help_unknown_cmd(const char *cmd)
                clean_cmdnames(&main_cmds);
                fprintf_ln(stderr,
                           _("WARNING: You called a Git command named '%s', "
-                            "which does not exist.\n"
-                            "Continuing under the assumption that you meant '%s'"),
-                       cmd, assumed);
-               if (autocorrect > 0) {
-                       fprintf_ln(stderr, _("in %0.1f seconds automatically..."),
-                               (float)autocorrect/10.0);
+                            "which does not exist."),
+                          cmd);
+               if (autocorrect < 0)
+                       fprintf_ln(stderr,
+                                  _("Continuing under the assumption that "
+                                    "you meant '%s'."),
+                                  assumed);
+               else {
+                       fprintf_ln(stderr,
+                                  _("Continuing in %0.1f seconds, "
+                                    "assuming that you meant '%s'."),
+                                  (float)autocorrect/10.0, assumed);
                        sleep_millisec(autocorrect * 100);
                }
                return assumed;
index bc178e88827a1a0558e9fbee1a6f18f6ede83df1..7a08470f8836e14824a215b29e0c3a5dbeba9c17 100644 (file)
@@ -10,7 +10,7 @@ merge_cmd () {
 
        if test "$meld_has_output_option" = true
        then
-               "$merge_tool_path" --output "$MERGED" \
+               "$merge_tool_path" --output="$MERGED" \
                        "$LOCAL" "$BASE" "$REMOTE"
        else
                "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"
index 39bcc168463fc7358ab7cb4e963e6ed8bde94804..294cfa43a4458c6758b8ac1529e48374931b66c8 100644 (file)
@@ -627,7 +627,7 @@ static void show_objects_for_type(
                        sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr);
 
                        if (bitmap_git.hashes)
-                               hash = ntohl(bitmap_git.hashes[entry->nr]);
+                               hash = get_be32(bitmap_git.hashes + entry->nr);
 
                        show_reach(sha1, object_type, 0, hash, bitmap_git.pack, entry->offset);
                }
index 679f8f4720fdf02ee37a4660632e08d861ff5432..42c4508ed6f57873dcbbb9af134ed2db61e3edaa 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -8564,7 +8564,7 @@ msgstr "\"auto-gc\" Modus aktivieren"
 #: builtin/gc.c:362
 msgid "force running gc even if there may be another gc running"
 msgstr ""
-"Ausführung von \"git gc\" erwzingen, selbst wenn ein anderes\n"
+"Ausführung von \"git gc\" erzwingen, selbst wenn ein anderes\n"
 "\"git gc\" bereits ausgeführt wird"
 
 #: builtin/gc.c:379
index d0f86f5d85cab6c470871cdd6e5ead526259bf6a..6cc812c2c72c2281299c44fd81376441bb16a0ec 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -783,29 +783,9 @@ struct format_commit_context {
        size_t body_off;
 
        /* The following ones are relative to the result struct strbuf. */
-       struct chunk abbrev_commit_hash;
-       struct chunk abbrev_tree_hash;
-       struct chunk abbrev_parent_hashes;
        size_t wrap_start;
 };
 
-static int add_again(struct strbuf *sb, struct chunk *chunk)
-{
-       if (chunk->len) {
-               strbuf_adddup(sb, chunk->off, chunk->len);
-               return 1;
-       }
-
-       /*
-        * We haven't seen this chunk before.  Our caller is surely
-        * going to add it the hard way now.  Remember the most likely
-        * start of the to-be-added chunk: the current end of the
-        * struct strbuf.
-        */
-       chunk->off = sb->len;
-       return 0;
-}
-
 static void parse_commit_header(struct format_commit_context *context)
 {
        const char *msg = context->message;
@@ -1147,24 +1127,16 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                return 1;
        case 'h':               /* abbreviated commit hash */
                strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
-               if (add_again(sb, &c->abbrev_commit_hash)) {
-                       strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
-                       return 1;
-               }
                strbuf_add_unique_abbrev(sb, commit->object.oid.hash,
                                         c->pretty_ctx->abbrev);
                strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
-               c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
                return 1;
        case 'T':               /* tree hash */
                strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid));
                return 1;
        case 't':               /* abbreviated tree hash */
-               if (add_again(sb, &c->abbrev_tree_hash))
-                       return 1;
                strbuf_add_unique_abbrev(sb, commit->tree->object.oid.hash,
                                         c->pretty_ctx->abbrev);
-               c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;
                return 1;
        case 'P':               /* parent hashes */
                for (p = commit->parents; p; p = p->next) {
@@ -1174,16 +1146,12 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                }
                return 1;
        case 'p':               /* abbreviated parent hashes */
-               if (add_again(sb, &c->abbrev_parent_hashes))
-                       return 1;
                for (p = commit->parents; p; p = p->next) {
                        if (p != commit->parents)
                                strbuf_addch(sb, ' ');
                        strbuf_add_unique_abbrev(sb, p->item->object.oid.hash,
                                                 c->pretty_ctx->abbrev);
                }
-               c->abbrev_parent_hashes.len = sb->len -
-                                             c->abbrev_parent_hashes.off;
                return 1;
        case 'm':               /* left/right/bottom */
                strbuf_addstr(sb, get_revision_mark(NULL, commit));
index f12da0dbb8b95fe234b07fcd536d794a1c6b5390..6238df448f8d7954b28630749336eceab70c67f3 100644 (file)
@@ -2428,6 +2428,14 @@ static int write_shared_index(struct index_state *istate,
                delete_tempfile(&temporary_sharedindex);
                return ret;
        }
+       ret = adjust_shared_perm(get_tempfile_path(&temporary_sharedindex));
+       if (ret) {
+               int save_errno = errno;
+               error("cannot fix permission bits on %s", get_tempfile_path(&temporary_sharedindex));
+               delete_tempfile(&temporary_sharedindex);
+               errno = save_errno;
+               return ret;
+       }
        ret = rename_tempfile(&temporary_sharedindex,
                              git_path("sharedindex.%s", sha1_to_hex(si->base->sha1)));
        if (!ret) {
index 8c72cf16145dc80edec90c6d4fb68811c0c65399..4b24e3bfda4bea9e64a419d6f7ec88a2366cd7f4 100644 (file)
@@ -1921,7 +1921,7 @@ static int apply_autostash(struct replay_opts *opts)
        argv_array_push(&child.args, "apply");
        argv_array_push(&child.args, stash_sha1.buf);
        if (!run_command(&child))
-               printf(_("Applied autostash.\n"));
+               fprintf(stderr, _("Applied autostash.\n"));
        else {
                struct child_process store = CHILD_PROCESS_INIT;
 
@@ -1935,10 +1935,11 @@ static int apply_autostash(struct replay_opts *opts)
                if (run_command(&store))
                        ret = error(_("cannot store %s"), stash_sha1.buf);
                else
-                       printf(_("Applying autostash resulted in conflicts.\n"
-                               "Your changes are safe in the stash.\n"
-                               "You can run \"git stash pop\" or"
-                               " \"git stash drop\" at any time.\n"));
+                       fprintf(stderr,
+                               _("Applying autostash resulted in conflicts.\n"
+                                 "Your changes are safe in the stash.\n"
+                                 "You can run \"git stash pop\" or"
+                                 " \"git stash drop\" at any time.\n"));
        }
 
        strbuf_release(&stash_sha1);
diff --git a/setup.c b/setup.c
index e3f7699a902aed20a83820067cf913df2f3750a9..2435186e448a6bf09616b0f1de1225ff2a666e48 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -982,6 +982,7 @@ const char *discover_git_directory(struct strbuf *gitdir)
                warning("ignoring git dir '%s': %s",
                        gitdir->buf + gitdir_offset, err.buf);
                strbuf_release(&err);
+               strbuf_setlen(gitdir, gitdir_offset);
                return NULL;
        }
 
index facea1bb560b57bbe7419dd1cce49f6b1172ddca..d5948826c8b2c4c4e6c2dbd4f036d0f814a7b8c2 100644 (file)
@@ -10,6 +10,9 @@
 #include <memory.h>
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef __unix__
+#include <sys/types.h> /* make sure macros like _BIG_ENDIAN visible */
+#endif
 #endif
 
 #ifdef SHA1DC_CUSTOM_INCLUDE_SHA1_C
 #include "sha1.h"
 #include "ubc_check.h"
 
+#if (defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
+     defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__)  || \
+     defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
+     defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
+     defined(__386) || defined(_M_X64) || defined(_M_AMD64))
+#define SHA1DC_ON_INTEL_LIKE_PROCESSOR
+#endif
 
 /*
    Because Little-Endian architectures are most common,
    If you are compiling on a big endian platform and your compiler does not define one of these,
    you will have to add whatever macros your tool chain defines to indicate Big-Endianness.
  */
-#ifdef SHA1DC_BIGENDIAN
-#undef SHA1DC_BIGENDIAN
-#endif
 
-#if (defined(_BYTE_ORDER) || defined(__BYTE_ORDER) || defined(__BYTE_ORDER__))
-
-#if ((defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)) || \
-     (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || \
-     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)) )
+#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
+/*
+ * Should detect Big Endian under GCC since at least 4.6.0 (gcc svn
+ * rev #165881). See
+ * https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
+ *
+ * This also works under clang since 3.2, it copied the GCC-ism. See
+ * clang.git's 3b198a97d2 ("Preprocessor: add __BYTE_ORDER__
+ * predefined macro", 2012-07-27)
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 #define SHA1DC_BIGENDIAN
 #endif
 
-#else
-
-#if (defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN) || defined(__BIG_ENDIAN__) || \
-     defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
-     defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \
-     defined(__sparc))
+/* Not under GCC-alike */
+#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN)
+/*
+ * Should detect Big Endian under glibc.git since 14245eb70e ("entered
+ * into RCS", 1992-11-25). Defined in <endian.h> which will have been
+ * brought in by standard headers. See glibc.git and
+ * https://sourceforge.net/p/predef/wiki/Endianness/
+ */
+#if __BYTE_ORDER == __BIG_ENDIAN
 #define SHA1DC_BIGENDIAN
 #endif
 
+/* Not under GCC-alike or glibc */
+#elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+/*
+ * *BSD and newlib (embeded linux, cygwin, etc).
+ * the defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) part prevents
+ * this condition from matching with Solaris/sparc.
+ * (Solaris defines only one endian macro)
+ */
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define SHA1DC_BIGENDIAN
 #endif
 
+/* Not under GCC-alike or glibc or *BSD or newlib */
+#elif (defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
+       defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \
+       defined(__sparc))
+/*
+ * Should define Big Endian for a whitelist of known processors. See
+ * https://sourceforge.net/p/predef/wiki/Endianness/ and
+ * http://www.oracle.com/technetwork/server-storage/solaris/portingtosolaris-138514.html
+ */
+#define SHA1DC_BIGENDIAN
+
+/* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist> */
+#elif defined(SHA1DC_ON_INTEL_LIKE_PROCESSOR)
+/*
+ * As a last resort before we do anything else we're not 100% sure
+ * about below, we blacklist specific processors here. We could add
+ * more, see e.g. https://wiki.debian.org/ArchitectureSpecificsMemo
+ */
+#else /* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist>  or <processor blacklist> */
+
+/* We do nothing more here for now */
+/*#error "Uncomment this to see if you fall through all the detection"*/
+
+#endif /* Big Endian detection */
+
 #if (defined(SHA1DC_FORCE_LITTLEENDIAN) && defined(SHA1DC_BIGENDIAN))
 #undef SHA1DC_BIGENDIAN
 #endif
 #endif
 /*ENDIANNESS SELECTION*/
 
-#if (defined SHA1DC_FORCE_UNALIGNED_ACCESS || \
-     defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
-     defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__)  || \
-     defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
-     defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
-     defined(__386) || defined(_M_X64) || defined(_M_AMD64))
-
+#if defined(SHA1DC_FORCE_UNALIGNED_ACCESS) || defined(SHA1DC_ON_INTEL_LIKE_PROCESSOR)
 #define SHA1DC_ALLOW_UNALIGNED_ACCESS
-
 #endif /*UNALIGNMENT DETECTION*/
 
 
index 00457940cfc163fed58b0206f5167c25c2c71b8a..9103bc75e482c81bbb8f9d89c72de2935fefcddc 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -204,13 +204,6 @@ void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)
        strbuf_setlen(sb, sb->len + sb2->len);
 }
 
-void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)
-{
-       strbuf_grow(sb, len);
-       memcpy(sb->buf + sb->len, sb->buf + pos, len);
-       strbuf_setlen(sb, sb->len + len);
-}
-
 void strbuf_addchars(struct strbuf *sb, int c, size_t n)
 {
        strbuf_grow(sb, n);
index 80047b1bb7b826699deff3e8c2590a2a00a5c121..d78525864935f84eb82e340b5ea3ffc9f755eb1e 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -263,12 +263,6 @@ static inline void strbuf_addstr(struct strbuf *sb, const char *s)
  */
 extern void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2);
 
-/**
- * Copy part of the buffer from a given position till a given length to the
- * end of the buffer.
- */
-extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
-
 /**
  * This function can be used to expand a format string containing
  * placeholders. To that end, it parses the string and calls the specified
index 13b7851f7c2feb87f63449d917380452e85c1f84..a37ef0422212eafdae4b4c0fae9e28d4a183117f 100755 (executable)
@@ -703,6 +703,12 @@ test_expect_success 'invalid unit' '
        test_i18ngrep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
 '
 
+test_expect_success 'line number is reported correctly' '
+       printf "[bool]\n\tvar\n" >invalid &&
+       test_must_fail git config -f invalid --path bool.var 2>actual &&
+       test_i18ngrep "line 2" actual
+'
+
 test_expect_success 'invalid stdin config' '
        echo "[broken" | test_must_fail git config --list --file - >output 2>&1 &&
        test_i18ngrep "bad config line 1 in standard input" output
index 1312004f8c8ab11b5aafe0eb1f1fb02f1e4f61d5..dfece751b572821464c390ee68f26d91624e2a33 100755 (executable)
@@ -19,10 +19,6 @@ test_expect_success 'shared = 0400 (faulty permission u-w)' '
        )
 '
 
-modebits () {
-       ls -l "$1" | sed -e 's|^\(..........\).*|\1|'
-}
-
 for u in 002 022
 do
        test_expect_success POSIXPERM "shared=1 does not clear bits preset by umask $u" '
@@ -88,7 +84,7 @@ do
 
                rm -f .git/info/refs &&
                git update-server-info &&
-               actual="$(modebits .git/info/refs)" &&
+               actual="$(test_modebits .git/info/refs)" &&
                verbose test "x$actual" = "x-$y"
 
        '
@@ -98,7 +94,7 @@ do
 
                rm -f .git/info/refs &&
                git update-server-info &&
-               actual="$(modebits .git/info/refs)" &&
+               actual="$(test_modebits .git/info/refs)" &&
                verbose test "x$actual" = "x-$x"
 
        '
@@ -111,7 +107,7 @@ test_expect_success POSIXPERM 'info/refs respects umask in unshared repo' '
        umask 002 &&
        git update-server-info &&
        echo "-rw-rw-r--" >expect &&
-       modebits .git/info/refs >actual &&
+       test_modebits .git/info/refs >actual &&
        test_cmp expect actual
 '
 
@@ -177,7 +173,7 @@ test_expect_success POSIXPERM 'remote init does not use config from cwd' '
        umask 0022 &&
        git init --bare child.git &&
        echo "-rw-r--r--" >expect &&
-       modebits child.git/config >actual &&
+       test_modebits child.git/config >actual &&
        test_cmp expect actual
 '
 
@@ -187,7 +183,7 @@ test_expect_success POSIXPERM 're-init respects core.sharedrepository (local)' '
        echo whatever >templates/foo &&
        git init --template=templates &&
        echo "-rw-rw-rw-" >expect &&
-       modebits .git/foo >actual &&
+       test_modebits .git/foo >actual &&
        test_cmp expect actual
 '
 
@@ -198,7 +194,7 @@ test_expect_success POSIXPERM 're-init respects core.sharedrepository (remote)'
        test_path_is_missing child.git/foo &&
        git init --bare --template=../templates child.git &&
        echo "-rw-rw-rw-" >expect &&
-       modebits child.git/foo >actual &&
+       test_modebits child.git/foo >actual &&
        test_cmp expect actual
 '
 
@@ -209,7 +205,7 @@ test_expect_success POSIXPERM 'template can set core.sharedrepository' '
        cp .git/config templates/config &&
        git init --bare --template=../templates child.git &&
        echo "-rw-rw-rw-" >expect &&
-       modebits child.git/HEAD >actual &&
+       test_modebits child.git/HEAD >actual &&
        test_cmp expect actual
 '
 
index ff50960ccaed9953c5738c9bbf602bf0d326e15a..69a0aa56d6d7b759e71a57d24b838fe21a544777 100755 (executable)
@@ -215,7 +215,9 @@ test_expect_success 'check line errors for malformed values' '
                br
        EOF
        test_expect_code 128 git br 2>result &&
-       test_i18ngrep "fatal: .*alias\.br.*\.git/config.*line 2" result
+       test_i18ngrep "missing value for .alias\.br" result &&
+       test_i18ngrep "fatal: .*\.git/config" result &&
+       test_i18ngrep "fatal: .*line 2" result
 '
 
 test_expect_success 'error on modifying repo config without repo' '
index adf0bc88ba510f08d9429ae0f2fb2b2d37424ff4..bb89e1a5db293dd886bff9df668bcaf187a58d11 100755 (executable)
@@ -573,7 +573,7 @@ test_expect_success 'fsck --name-objects' '
                remove_object $(git rev-parse julius:caesar.t) &&
                test_must_fail git fsck --name-objects >out &&
                tree=$(git rev-parse --verify julius:) &&
-               grep "$tree (\(refs/heads/master\|HEAD\)@{[0-9]*}:" out
+               egrep "$tree \((refs/heads/master|HEAD)@\{[0-9]*\}:" out
        )
 '
 
index af3ec0da5ac0f5e0f6e19616d9c55b611ba5a701..22f69a410ba8194bbdff70471f5b3e746af116da 100755 (executable)
@@ -370,4 +370,34 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"
        test $(ls .git/sharedindex.* | wc -l) -le 2
 '
 
+while read -r mode modebits
+do
+       test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
+               # Remove existing shared index files
+               git config core.splitIndex false &&
+               git update-index --force-remove one &&
+               rm -f .git/sharedindex.* &&
+               # Create one new shared index file
+               git config core.sharedrepository "$mode" &&
+               git config core.splitIndex true &&
+               : >one &&
+               git update-index --add one &&
+               echo "$modebits" >expect &&
+               test_modebits .git/index >actual &&
+               test_cmp expect actual &&
+               shared=$(ls .git/sharedindex.*) &&
+               case "$shared" in
+               *" "*)
+                       # we have more than one???
+                       false ;;
+               *)
+                       test_modebits "$shared" >actual &&
+                       test_cmp expect actual ;;
+               esac
+       '
+done <<\EOF
+0666 -rw-rw-rw-
+0642 -rw-r---w-
+EOF
+
 test_done
index 5bd0275930b715c25507fc9744c8946e7f73900b..37821d245433f757fa13f0a3e27da0312bebb7db 100755 (executable)
@@ -169,6 +169,13 @@ test_expect_success 'reflog for the branch shows state before rebase' '
        test $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1)
 '
 
+test_expect_success 'reflog for the branch shows correct finish message' '
+       printf "rebase -i (finish): refs/heads/branch1 onto %s\n" \
+               "$(git rev-parse branch2)" >expected &&
+       git log -g --pretty=%gs -1 refs/heads/branch1 >actual &&
+       test_cmp expected actual
+'
+
 test_expect_success 'exchange two commits' '
        set_fake_editor &&
        FAKE_LINES="2 1" git rebase -i HEAD~2 &&
index ab8a63e8d6dc643b28eb0c74ba3f032b7532226f..e24370066012fcb441aa0c59ff9c0c34e1d37e9c 100755 (executable)
@@ -33,7 +33,123 @@ test_expect_success setup '
        git commit -m "related commit"
 '
 
-testrebase() {
+create_expected_success_am () {
+       cat >expected <<-EOF
+       $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
+       HEAD is now at $(git rev-parse --short feature-branch) third commit
+       First, rewinding head to replay your work on top of it...
+       Applying: second commit
+       Applying: third commit
+       Applied autostash.
+       EOF
+}
+
+create_expected_success_interactive () {
+       q_to_cr >expected <<-EOF
+       $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
+       HEAD is now at $(git rev-parse --short feature-branch) third commit
+       Rebasing (1/2)QRebasing (2/2)QApplied autostash.
+       Successfully rebased and updated refs/heads/rebased-feature-branch.
+       EOF
+}
+
+create_expected_success_merge () {
+       cat >expected <<-EOF
+       $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
+       HEAD is now at $(git rev-parse --short feature-branch) third commit
+       First, rewinding head to replay your work on top of it...
+       Merging unrelated-onto-branch with HEAD~1
+       Merging:
+       $(git rev-parse --short unrelated-onto-branch) unrelated commit
+       $(git rev-parse --short feature-branch^) second commit
+       found 1 common ancestor:
+       $(git rev-parse --short feature-branch~2) initial commit
+       [detached HEAD $(git rev-parse --short rebased-feature-branch~1)] second commit
+        Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:14:13 2005 -0700
+        2 files changed, 2 insertions(+)
+        create mode 100644 file1
+        create mode 100644 file2
+       Committed: 0001 second commit
+       Merging unrelated-onto-branch with HEAD~0
+       Merging:
+       $(git rev-parse --short rebased-feature-branch~1) second commit
+       $(git rev-parse --short feature-branch) third commit
+       found 1 common ancestor:
+       $(git rev-parse --short feature-branch~1) second commit
+       [detached HEAD $(git rev-parse --short rebased-feature-branch)] third commit
+        Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:15:13 2005 -0700
+        1 file changed, 1 insertion(+)
+        create mode 100644 file3
+       Committed: 0002 third commit
+       All done.
+       Applied autostash.
+       EOF
+}
+
+create_expected_failure_am () {
+       cat >expected <<-EOF
+       $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
+       HEAD is now at $(git rev-parse --short feature-branch) third commit
+       First, rewinding head to replay your work on top of it...
+       Applying: second commit
+       Applying: third commit
+       Applying autostash resulted in conflicts.
+       Your changes are safe in the stash.
+       You can run "git stash pop" or "git stash drop" at any time.
+       EOF
+}
+
+create_expected_failure_interactive () {
+       q_to_cr >expected <<-EOF
+       $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
+       HEAD is now at $(git rev-parse --short feature-branch) third commit
+       Rebasing (1/2)QRebasing (2/2)QApplying autostash resulted in conflicts.
+       Your changes are safe in the stash.
+       You can run "git stash pop" or "git stash drop" at any time.
+       Successfully rebased and updated refs/heads/rebased-feature-branch.
+       EOF
+}
+
+create_expected_failure_merge () {
+       cat >expected <<-EOF
+       $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
+       HEAD is now at $(git rev-parse --short feature-branch) third commit
+       First, rewinding head to replay your work on top of it...
+       Merging unrelated-onto-branch with HEAD~1
+       Merging:
+       $(git rev-parse --short unrelated-onto-branch) unrelated commit
+       $(git rev-parse --short feature-branch^) second commit
+       found 1 common ancestor:
+       $(git rev-parse --short feature-branch~2) initial commit
+       [detached HEAD $(git rev-parse --short rebased-feature-branch~1)] second commit
+        Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:14:13 2005 -0700
+        2 files changed, 2 insertions(+)
+        create mode 100644 file1
+        create mode 100644 file2
+       Committed: 0001 second commit
+       Merging unrelated-onto-branch with HEAD~0
+       Merging:
+       $(git rev-parse --short rebased-feature-branch~1) second commit
+       $(git rev-parse --short feature-branch) third commit
+       found 1 common ancestor:
+       $(git rev-parse --short feature-branch~1) second commit
+       [detached HEAD $(git rev-parse --short rebased-feature-branch)] third commit
+        Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:15:13 2005 -0700
+        1 file changed, 1 insertion(+)
+        create mode 100644 file3
+       Committed: 0002 third commit
+       All done.
+       Applying autostash resulted in conflicts.
+       Your changes are safe in the stash.
+       You can run "git stash pop" or "git stash drop" at any time.
+       EOF
+}
+
+testrebase () {
        type=$1
        dotest=$2
 
@@ -51,14 +167,20 @@ testrebase() {
                test_config rebase.autostash true &&
                git reset --hard &&
                git checkout -b rebased-feature-branch feature-branch &&
-               test_when_finished git branch -D rebased-feature-branch &&
                echo dirty >>file3 &&
-               git rebase$type unrelated-onto-branch &&
+               git rebase$type unrelated-onto-branch >actual 2>&1 &&
                grep unrelated file4 &&
                grep dirty file3 &&
                git checkout feature-branch
        '
 
+       test_expect_success "rebase$type --autostash: check output" '
+               test_when_finished git branch -D rebased-feature-branch &&
+               suffix=${type#\ --} && suffix=${suffix:-am} &&
+               create_expected_success_$suffix &&
+               test_i18ncmp expected actual
+       '
+
        test_expect_success "rebase$type: dirty index, non-conflicting rebase" '
                test_config rebase.autostash true &&
                git reset --hard &&
@@ -137,10 +259,9 @@ testrebase() {
                test_config rebase.autostash true &&
                git reset --hard &&
                git checkout -b rebased-feature-branch feature-branch &&
-               test_when_finished git branch -D rebased-feature-branch &&
                echo dirty >file4 &&
                git add file4 &&
-               git rebase$type unrelated-onto-branch &&
+               git rebase$type unrelated-onto-branch >actual 2>&1 &&
                test_path_is_missing $dotest &&
                git reset --hard &&
                grep unrelated file4 &&
@@ -149,6 +270,13 @@ testrebase() {
                git stash pop &&
                grep dirty file4
        '
+
+       test_expect_success "rebase$type: check output with conflicting stash" '
+               test_when_finished git branch -D rebased-feature-branch &&
+               suffix=${type#\ --} && suffix=${suffix:-am} &&
+               create_expected_failure_$suffix &&
+               test_i18ncmp expected actual
+       '
 }
 
 test_expect_success "rebase: fast-forward rebase" '
index 2ecb43a61652032862d5a264ede8af473ef345e1..2f3e7cea64e897299d87196135032de22050354b 100755 (executable)
@@ -477,4 +477,12 @@ test_expect_success 'add -p does not expand argument lists' '
        ! grep not-changed trace.out
 '
 
+test_expect_success 'hunk-editing handles custom comment char' '
+       git reset --hard &&
+       echo change >>file &&
+       test_config core.commentChar "\$" &&
+       echo e | GIT_EDITOR=true git add -p &&
+       git diff --exit-code
+'
+
 test_done
index 135addbfbdae8e39ba0462e71278f41dfc552620..f542d2929d2316fa8d858fc29c1bdfb5ef4c3c71 100755 (executable)
@@ -3,84 +3,75 @@
 # Copyright (c) 2005 Junio C Hamano
 #
 
-test_description='Same rename detection as t4003 but testing diff-raw.
+test_description='Same rename detection as t4003 but testing diff-raw.'
 
-'
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/diff-lib.sh ;# test-lib chdir's into trash
 
-test_expect_success \
-    'prepare reference tree' \
-    'cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
-     echo frotz >rezrov &&
-    git update-index --add COPYING rezrov &&
-    tree=$(git write-tree) &&
-    echo $tree'
-
-test_expect_success \
-    'prepare work tree' \
-    'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 &&
-    sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 &&
-    rm -f COPYING &&
-    git update-index --add --remove COPYING COPYING.?'
+test_expect_success 'setup reference tree' '
+       cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
+       echo frotz >rezrov &&
+       git update-index --add COPYING rezrov &&
+       tree=$(git write-tree) &&
+       echo $tree &&
+       sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 &&
+       sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 &&
+       origoid=$(git hash-object COPYING) &&
+       oid1=$(git hash-object COPYING.1) &&
+       oid2=$(git hash-object COPYING.2)
+'
 
+################################################################
 # tree has COPYING and rezrov.  work tree has COPYING.1 and COPYING.2,
 # both are slightly edited, and unchanged rezrov.  We say COPYING.1
 # and COPYING.2 are based on COPYING, and do not say anything about
 # rezrov.
 
-git diff-index -C $tree >current
-
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 R1234 COPYING COPYING.2
-EOF
+test_expect_success 'validate output from rename/copy detection (#1)' '
+       rm -f COPYING &&
+       git update-index --add --remove COPYING COPYING.? &&
 
-test_expect_success \
-    'validate output from rename/copy detection (#1)' \
-    'compare_diff_raw current expected'
+       cat <<-EOF >expected &&
+       :100644 100644 $origoid $oid1 C1234     COPYING COPYING.1
+       :100644 100644 $origoid $oid2 R1234     COPYING COPYING.2
+       EOF
+       git diff-index -C $tree >current &&
+       compare_diff_raw expected current
+'
 
 ################################################################
-
-test_expect_success \
-    'prepare work tree again' \
-    'mv COPYING.2 COPYING &&
-     git update-index --add --remove COPYING COPYING.1 COPYING.2'
-
 # tree has COPYING and rezrov.  work tree has COPYING and COPYING.1,
 # both are slightly edited, and unchanged rezrov.  We say COPYING.1
 # is based on COPYING and COPYING is still there, and do not say anything
 # about rezrov.
 
-git diff-index -C $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M     COPYING
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1
-EOF
+test_expect_success 'validate output from rename/copy detection (#2)' '
+       mv COPYING.2 COPYING &&
+       git update-index --add --remove COPYING COPYING.1 COPYING.2 &&
 
-test_expect_success \
-    'validate output from rename/copy detection (#2)' \
-    'compare_diff_raw current expected'
+       cat <<-EOF >expected &&
+       :100644 100644 $origoid $oid2 M COPYING
+       :100644 100644 $origoid $oid1 C1234     COPYING COPYING.1
+       EOF
+       git diff-index -C $tree >current &&
+       compare_diff_raw current expected
+'
 
 ################################################################
-
 # tree has COPYING and rezrov.  work tree has the same COPYING and
 # copy-edited COPYING.1, and unchanged rezrov.  We should not say
 # anything about rezrov or COPYING, since the revised again diff-raw
 # nows how to say Copy.
 
-test_expect_success \
-    'prepare work tree once again' \
-    'cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
-     git update-index --add --remove COPYING COPYING.1'
-
-git diff-index -C --find-copies-harder $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1
-EOF
+test_expect_success 'validate output from rename/copy detection (#3)' '
+       cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
+       git update-index --add --remove COPYING COPYING.1 &&
 
-test_expect_success \
-    'validate output from rename/copy detection (#3)' \
-    'compare_diff_raw current expected'
+       cat <<-EOF >expected &&
+       :100644 100644 $origoid $oid1 C1234     COPYING COPYING.1
+       EOF
+       git diff-index -C --find-copies-harder $tree >current &&
+       compare_diff_raw current expected
+'
 
 test_done
index c268298eaf5672c649ca3e4815dc4f43d71efece..5cdd76dfa726d32226b1dd625d21d6280125afb7 100755 (executable)
@@ -13,7 +13,9 @@ test_expect_success setup '
        echo modified >file &&
        git diff --stat -p >patch-0.txt &&
        chmod +x file &&
-       git diff --stat -p >patch-1.txt
+       git diff --stat -p >patch-1.txt &&
+       sed "s/^\(new mode \).*/\1/" <patch-1.txt >patch-empty-mode.txt &&
+       sed "s/^\(new mode \).*/\1garbage/" <patch-1.txt >patch-bogus-mode.txt
 '
 
 test_expect_success FILEMODE 'same mode (no index)' '
@@ -59,4 +61,16 @@ test_expect_success FILEMODE 'mode update (index only)' '
        git ls-files -s file | grep "^100755"
 '
 
+test_expect_success FILEMODE 'empty mode is rejected' '
+       git reset --hard &&
+       test_must_fail git apply patch-empty-mode.txt 2>err &&
+       test_i18ngrep "invalid mode" err
+'
+
+test_expect_success FILEMODE 'bogus mode is rejected' '
+       git reset --hard &&
+       test_must_fail git apply patch-bogus-mode.txt 2>err &&
+       test_i18ngrep "invalid mode" err
+'
+
 test_done
index 2ecb4216b7179ef836836d90a5f76f5e4349ca23..c5ed3b17c4a1196e154affc346b5fd3d4e0a7abf 100755 (executable)
@@ -35,4 +35,28 @@ test_expect_success 'apply diff with inconsistent filenames in headers' '
        test_i18ngrep "inconsistent old filename" err
 '
 
+test_expect_success 'apply diff with new filename missing from headers' '
+       cat >missing_new_filename.diff <<-\EOF &&
+       diff --git a/f b/f
+       index 0000000..d00491f
+       --- a/f
+       @@ -0,0 +1 @@
+       +1
+       EOF
+       test_must_fail git apply missing_new_filename.diff 2>err &&
+       test_i18ngrep "lacks filename information" err
+'
+
+test_expect_success 'apply diff with old filename missing from headers' '
+       cat >missing_old_filename.diff <<-\EOF &&
+       diff --git a/f b/f
+       index d00491f..0000000
+       +++ b/f
+       @@ -1 +0,0 @@
+       -1
+       EOF
+       test_must_fail git apply missing_old_filename.diff 2>err &&
+       test_i18ngrep "lacks filename information" err
+'
+
 test_done
index 4b0a374b63f4128405c88fdb2410fb679bdd06a1..6d9287231826ece18873b531186907cd75ef7461 100755 (executable)
@@ -29,4 +29,22 @@ test_expect_success 'apply exits non-zero with no-op patch' '
        test_must_fail git apply --check input
 '
 
+test_expect_success 'invalid combination: create and copy' '
+       test_must_fail git apply --check - <<-\EOF
+       diff --git a/1 b/2
+       new file mode 100644
+       copy from 1
+       copy to 2
+       EOF
+'
+
+test_expect_success 'invalid combination: create and rename' '
+       test_must_fail git apply --check - <<-\EOF
+       diff --git a/1 b/2
+       new file mode 100644
+       rename from 1
+       rename to 2
+       EOF
+'
+
 test_done
index 5bcb288f5c4d02e7994d745bc07485bf1bf6c116..464ffdd147abbae354ae3adfe593b89a37d5c726 100755 (executable)
@@ -119,8 +119,11 @@ test_expect_success GPG 'signed push sends push certificate' '
                sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert
        ) >expect &&
 
-       grep "$(git rev-parse noop ff) refs/heads/ff" dst/push-cert &&
-       grep "$(git rev-parse noop noff) refs/heads/noff" dst/push-cert &&
+       noop=$(git rev-parse noop) &&
+       ff=$(git rev-parse ff) &&
+       noff=$(git rev-parse noff) &&
+       grep "$noop $ff refs/heads/ff" dst/push-cert &&
+       grep "$noop $noff refs/heads/noff" dst/push-cert &&
        test_cmp expect dst/push-cert-status
 '
 
@@ -200,8 +203,11 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '
                sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert
        ) >expect &&
 
-       grep "$(git rev-parse noop ff) refs/heads/ff" dst/push-cert &&
-       grep "$(git rev-parse noop noff) refs/heads/noff" dst/push-cert &&
+       noop=$(git rev-parse noop) &&
+       ff=$(git rev-parse ff) &&
+       noff=$(git rev-parse noff) &&
+       grep "$noop $ff refs/heads/ff" dst/push-cert &&
+       grep "$noop $noff refs/heads/noff" dst/push-cert &&
        test_cmp expect dst/push-cert-status
 '
 
index 4f3794d415e95b0b65ca29b829ce278b45ea5dbd..20b4d83c281e2fde8812f309bdebef012c6ecb74 100755 (executable)
@@ -391,6 +391,17 @@ test_expect_success TTY 'core.pager in repo config works and retains cwd' '
        )
 '
 
+test_expect_success TTY 'core.pager is found via alias in subdirectory' '
+       sane_unset GIT_PAGER &&
+       test_config core.pager "cat >via-alias" &&
+       (
+               cd sub &&
+               rm -f via-alias &&
+               test_terminal git -c alias.r="-p rev-parse" r HEAD &&
+               test_path_is_file via-alias
+       )
+'
+
 test_doesnt_paginate      expect_failure test_must_fail 'git -p nonsense'
 
 test_pager_choices                       'git shortlog'
index 5edcc6edfe651f638921b9148be9579312a47adc..35ea0b707474342a323e02ce614e736c1acfe2eb 100755 (executable)
@@ -1494,7 +1494,7 @@ EOF
 test_expect_success 'git commit -m will commit a staged but ignored submodule' '
        git commit -uno -m message &&
        git status -s --ignore-submodules=dirty >output &&
-        test_i18ngrep ! "^M. sm" output &&
+       test_i18ngrep ! "^M. sm" output &&
        git config --remove-section submodule.subname &&
        git config -f .gitmodules  --remove-section submodule.subname
 '
index 5ee124332a713b1dec984090401b08efb2b9cfe9..db622c3555dcbf7f66b45c05df5279b6db6b2a9e 100644 (file)
@@ -216,6 +216,11 @@ test_chmod () {
        git update-index --add "--chmod=$@"
 }
 
+# Get the modebits from a file.
+test_modebits () {
+       ls -l "$1" | sed -e 's|^\(..........\).*|\1|'
+}
+
 # Unset a configuration variable, but don't fail if it doesn't exist.
 test_unconfig () {
        config_dir=