Merge branch 'jk/get-oid-indexed-object-name'
authorJunio C Hamano <gitster@pobox.com>
Sun, 19 May 2019 07:45:35 +0000 (16:45 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 19 May 2019 07:45:35 +0000 (16:45 +0900)
The codepath to parse :<path> that obtains the object name for an
indexed object has been made more robust.

* jk/get-oid-indexed-object-name:
get_oid: handle NULL repo->index

64 files changed:
Documentation/config/stash.txt
Documentation/git-branch.txt
Documentation/git-checkout.txt
Documentation/git-difftool.txt
Documentation/git-mergetool--lib.txt
Documentation/git-mergetool.txt
Documentation/git.txt
Makefile
branch.c
builtin/clone.c
builtin/difftool.c
builtin/multi-pack-index.c
builtin/pack-objects.c
builtin/pack-refs.c
builtin/show-ref.c
builtin/submodule--helper.c
builtin/tag.c
cache.h
ci/install-dependencies.sh
commit-graph.c
compat/mingw.c
compat/mingw.h
config.mak.uname
contrib/diff-highlight/DiffHighlight.pm
fsmonitor.c
git-cvsexportcommit.perl
git-difftool--helper.sh
git-mergetool--lib.sh
git-mergetool.sh
http-push.c
http.c
midx.c
midx.h
notes.h
object-store.h
packfile.c
parse-options.c
parse-options.h
pkt-line.c
read-cache.c
sha1-name.c
sha1collisiondetection
sha1dc/sha1.c
t/check-non-portable-shell.pl
t/helper/test-parse-options.c
t/helper/test-read-cache.c
t/lib-httpd/apache.conf
t/perf/README
t/perf/aggregate.perl
t/perf/perf-lib.sh
t/perf/run
t/t0040-parse-options.sh
t/t2018-checkout-branch.sh
t/t3200-branch.sh
t/t4253-am-keep-cr-dos.sh
t/t5580-clone-push-unc.sh
t/t6500-gc.sh
t/t7004-tag.sh
t/t7519-status-fsmonitor.sh
t/t7610-mergetool.sh
t/t7800-difftool.sh
t/test-lib.sh
upload-pack.c
wt-status.c
index c583d46d6b66b39a74f6583313143dabd4bb53c1..7710758efb5340c15e4df93d9669800bfb5cec16 100644 (file)
@@ -1,3 +1,18 @@
+stash.useBuiltin::
+       Set to `false` to use the legacy shell script implementation of
+       linkgit:git-stash[1]. Is `true` by default, which means use
+       the built-in rewrite of it in C.
++
+The C rewrite is first included with Git version 2.22 (and Git for Windows
+version 2.19). This option serves an an escape hatch to re-enable the
+legacy version in case any bugs are found in the rewrite. This option and
+the shell script version of linkgit:git-stash[1] will be removed in some
+future release.
++
+If you find some reason to set this option to `false`, other than
+one-off testing, you should report the behavior difference as a bug in
+Git (see https://git-scm.com/community for details).
+
 stash.showPatch::
        If this is set to true, the `git stash show` command without an
        option will show the stash entry in patch form.  Defaults to false.
index 0cd87ddeff205ac6b5a92260f690e642f16d0875..6ebd512b4f3344c2f166f5bb09f0b5c6eb96ab03 100644 (file)
@@ -45,7 +45,11 @@ argument is missing it defaults to `HEAD` (i.e. the tip of the current
 branch).
 
 The command's second form creates a new branch head named <branchname>
-which points to the current `HEAD`, or <start-point> if given.
+which points to the current `HEAD`, or <start-point> if given. As a
+special case, for <start-point>, you may use `"A...B"` as a shortcut for
+the merge base of `A` and `B` if there is exactly one merge base. You
+can leave out at most one of `A` and `B`, in which case it defaults to
+`HEAD`.
 
 Note that this will create the new branch, but it will not switch the
 working tree to it; use "git checkout <newbranch>" to switch to the
index 877e5f503a66145912886c14917f0e68512e6284..964f912d29ee92d55a3c98d40cc41941e7db743a 100644 (file)
@@ -313,6 +313,10 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
 <start_point>::
        The name of a commit at which to start the new branch; see
        linkgit:git-branch[1] for details. Defaults to HEAD.
++
+As a special case, you may use `"A...B"` as a shortcut for the
+merge base of `A` and `B` if there is exactly one merge base. You can
+leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
 
 <tree-ish>::
        Tree to checkout from (when paths are given). If not specified,
index 96c26e6aa82c98da1652023f0d04b4b63c8a4944..484c485fd06c9d52e09b5e7324f5f13fd444e4f9 100644 (file)
@@ -90,7 +90,9 @@ instead.  `--no-symlinks` is the default on Windows.
        When 'git-difftool' is invoked with the `-g` or `--gui` option
        the default diff tool will be read from the configured
        `diff.guitool` variable instead of `diff.tool`. The `--no-gui`
-       option can be used to override this setting.
+       option can be used to override this setting. If `diff.guitool`
+       is not set, we will fallback in the order of `merge.guitool`,
+       `diff.tool`, `merge.tool` until a tool is found.
 
 --[no-]trust-exit-code::
        'git-difftool' invokes a diff tool individually on each file.
index 055550b2bcc805780396b83b162a328230c0a1c6..4da9d240962f24da7daa7ebde7b4f0db4634cdd8 100644 (file)
@@ -28,7 +28,9 @@ to define the operation mode for the functions listed below.
 FUNCTIONS
 ---------
 get_merge_tool::
-       returns a merge tool.
+       returns a merge tool. the return code is 1 if we returned a guessed
+       merge tool, else 0. '$GIT_MERGETOOL_GUI' may be set to 'true' to
+       search for the appropriate guitool.
 
 get_merge_tool_cmd::
        returns the custom command for a merge tool.
index 0c7975a0507a35f9624516f0844ad11cd5141d50..6b14702e78498ee45f67e0084bea429d484b28cf 100644 (file)
@@ -83,7 +83,9 @@ success of the resolution after the custom tool has exited.
 --gui::
        When 'git-mergetool' is invoked with the `-g` or `--gui` option
        the default merge tool will be read from the configured
-       `merge.guitool` variable instead of `merge.tool`.
+       `merge.guitool` variable instead of `merge.tool`. If
+       `merge.guitool` is not set, we will fallback to the tool
+       configured under `merge.tool`.
 
 --no-gui::
        This overrides a previous `-g` or `--gui` setting and reads the
index 6d1f2fd9ae9e993e46d935f835bdfec4e6f686e1..72adfcc5e24b783f6924655088a968a5357b188e 100644 (file)
@@ -660,6 +660,27 @@ of clones and fetches.
        When a curl trace is enabled (see `GIT_TRACE_CURL` above), do not dump
        data (that is, only dump info lines and headers).
 
+`GIT_TR2`::
+       Enables more detailed trace messages from the "trace2" library.
+       Output from `GIT_TR2` is a simple text-based format for human
+       readability.
++
+The `GIT_TR2` variables can take many values. Any value available to
+the `GIT_TRACE` variables is also available to `GIT_TR2`. The `GIT_TR2`
+variables can also specify a Unix Domain Socket. See
+link:technical/api-trace2.html[Trace2 documentation] for full details.
+
+`GIT_TR2_EVENT`::
+       This setting writes a JSON-based format that is suited for machine
+       interpretation. See link:technical/api-trace2.html[Trace2 documentation]
+       for full details.
+
+`GIT_TR2_PERF`::
+       In addition to the text-based messages available in `GIT_TR2`, this
+       setting writes a column-based format for understanding nesting
+       regions. See link:technical/api-trace2.html[Trace2 documentation]
+       for full details.
+
 `GIT_REDACT_COOKIES`::
        This can be set to a comma-separated list of strings. When a curl trace
        is enabled (see `GIT_TRACE_CURL` above), whenever a "Cookies:" header
index f965509b3c0fbaac60af3305401b7a3c6ea9b865..8a7e2353520ddd7e0c8074d2b32d0441d97c1597 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1171,8 +1171,11 @@ PTHREAD_CFLAGS =
 SPARSE_FLAGS ?=
 SP_EXTRA_FLAGS =
 
-# For the 'coccicheck' target
+# For the 'coccicheck' target; setting SPATCH_BATCH_SIZE higher will
+# usually result in less CPU usage at the cost of higher peak memory.
+# Setting it to 0 will feed all files in a single spatch invocation.
 SPATCH_FLAGS = --all-includes --patch .
+SPATCH_BATCH_SIZE = 1
 
 include config.mak.uname
 -include config.mak.autogen
@@ -2807,12 +2810,14 @@ endif
 
 %.cocci.patch: %.cocci $(COCCI_SOURCES)
        @echo '    ' SPATCH $<; \
-       ret=0; \
-       for f in $(COCCI_SOURCES); do \
-               $(SPATCH) --sp-file $< $$f $(SPATCH_FLAGS) || \
-                       { ret=$$?; break; }; \
-       done >$@+ 2>$@.log; \
-       if test $$ret != 0; \
+       if test $(SPATCH_BATCH_SIZE) = 0; then \
+               limit=; \
+       else \
+               limit='-n $(SPATCH_BATCH_SIZE)'; \
+       fi; \
+       if ! echo $(COCCI_SOURCES) | xargs $$limit \
+               $(SPATCH) --sp-file $< $(SPATCH_FLAGS) \
+               >$@+ 2>$@.log; \
        then \
                cat $@.log; \
                exit 1; \
index 643694542a51634e0bc5cbef92226913d16ccbe7..a594cc23e25458250885244f477a5d4879df2537 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -269,7 +269,7 @@ void create_branch(struct repository *r,
        }
 
        real_ref = NULL;
-       if (get_oid(start_name, &oid)) {
+       if (get_oid_mb(start_name, &oid)) {
                if (explicit_tracking) {
                        if (advice_set_upstream_failure) {
                                error(_(upstream_missing), start_name);
index ffdd94e8f66193626e343e4cd0b14bd12d262d0e..85b0d3155de0d9ee9257ac44acc699c004022836 100644 (file)
@@ -99,10 +99,7 @@ static struct option builtin_clone_options[] = {
                    N_("don't use local hardlinks, always copy")),
        OPT_BOOL('s', "shared", &option_shared,
                    N_("setup as shared repository")),
-       { OPTION_CALLBACK, 0, "recursive", &option_recurse_submodules,
-         N_("pathspec"), N_("initialize submodules in the clone"),
-         PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, recurse_submodules_cb,
-         (intptr_t)"." },
+       OPT_ALIAS(0, "recursive", "recurse-submodules"),
        { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules,
          N_("pathspec"), N_("initialize submodules in the clone"),
          PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." },
index 04ffa1d943d6e3a22eb919a21ad775c0bb29a6db..53188df71438ad83186bcae37a8742704ae048a5 100644 (file)
@@ -24,7 +24,6 @@
 #include "object-store.h"
 #include "dir.h"
 
-static char *diff_gui_tool;
 static int trust_exit_code;
 
 static const char *const builtin_difftool_usage[] = {
@@ -34,11 +33,6 @@ static const char *const builtin_difftool_usage[] = {
 
 static int difftool_config(const char *var, const char *value, void *cb)
 {
-       if (!strcmp(var, "diff.guitool")) {
-               diff_gui_tool = xstrdup(value);
-               return 0;
-       }
-
        if (!strcmp(var, "difftool.trustexitcode")) {
                trust_exit_code = git_config_bool(var, value);
                return 0;
@@ -735,8 +729,11 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)
                setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1);
        }
 
-       if (use_gui_tool && diff_gui_tool && *diff_gui_tool)
-               setenv("GIT_DIFF_TOOL", diff_gui_tool, 1);
+       if (use_gui_tool + !!difftool_cmd + !!extcmd > 1)
+               die(_("--gui, --tool and --extcmd are mutually exclusive"));
+
+       if (use_gui_tool)
+               setenv("GIT_MERGETOOL_GUI", "true", 1);
        else if (difftool_cmd) {
                if (*difftool_cmd)
                        setenv("GIT_DIFF_TOOL", difftool_cmd, 1);
index ae6e476ad567e57e5a1e308d7901b0a0c331640f..72dfd3dadc7bf8037d4bd11d24aabca6a56a5fa8 100644 (file)
@@ -46,7 +46,7 @@ int cmd_multi_pack_index(int argc, const char **argv,
        if (!strcmp(argv[0], "write"))
                return write_midx_file(opts.object_dir);
        if (!strcmp(argv[0], "verify"))
-               return verify_midx_file(opts.object_dir);
+               return verify_midx_file(the_repository, opts.object_dir);
 
        die(_("unrecognized verb: %s"), argv[0]);
 }
index 9f424aababe6beacec572d6ef7dcd3b5fa18de44..41d7fc59830c090d8b0422980528e4ea429c9e6b 100644 (file)
@@ -1080,7 +1080,7 @@ static int want_object_in_pack(const struct object_id *oid,
 
        for (m = get_multi_pack_index(the_repository); m; m = m->next) {
                struct pack_entry e;
-               if (fill_midx_entry(oid, &e, m)) {
+               if (fill_midx_entry(the_repository, oid, &e, m)) {
                        struct packed_git *p = e.p;
                        off_t offset;
 
index f3353564f99205b278362484abcdf1537058ef29..cfbd5c36c7640bc841a68bb5a524f025c43212fd 100644 (file)
@@ -1,4 +1,5 @@
 #include "builtin.h"
+#include "config.h"
 #include "parse-options.h"
 #include "refs.h"
 #include "repository.h"
@@ -16,6 +17,7 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
                OPT_BIT(0, "prune", &flags, N_("prune loose refs (default)"), PACK_REFS_PRUNE),
                OPT_END(),
        };
+       git_config(git_default_config, NULL);
        if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
                usage_with_options(pack_refs_usage, opts);
        return refs_pack_refs(get_main_ref_store(the_repository), flags);
index 6a706c02a6f9782ee4abb289cfafe468253aca1f..6456da70cc2c4d6a86c2466c483dd815b15bbb45 100644 (file)
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "cache.h"
+#include "config.h"
 #include "refs.h"
 #include "object-store.h"
 #include "object.h"
@@ -182,6 +183,8 @@ static const struct option show_ref_options[] = {
 
 int cmd_show_ref(int argc, const char **argv, const char *prefix)
 {
+       git_config(git_default_config, NULL);
+
        argc = parse_options(argc, argv, prefix, show_ref_options,
                             show_ref_usage, 0);
 
index 8c72ea864c81d8763ac48ee7e1e7795e1323ddb3..0bf4aa088e0ca4bf6378d121cfc23e0f42ac3af4 100644 (file)
@@ -1301,7 +1301,7 @@ static int add_possible_reference_from_superproject(
                                die(_("submodule '%s' cannot add alternate: %s"),
                                    sas->submodule_name, err.buf);
                        case SUBMODULE_ALTERNATE_ERROR_INFO:
-                               fprintf(stderr, _("submodule '%s' cannot add alternate: %s"),
+                               fprintf_ln(stderr, _("submodule '%s' cannot add alternate: %s"),
                                        sas->submodule_name, err.buf);
                        case SUBMODULE_ALTERNATE_ERROR_IGNORE:
                                ; /* nothing */
index 1debd3a11c2ec0aa44fa75ebd908f78a46f371a1..ef37dccf864932a31c019775cdad6d33207941a1 100644 (file)
@@ -207,7 +207,7 @@ struct create_tag_options {
 };
 
 static const char message_advice_nested_tag[] =
-       N_("You have created a nested tag. The object referred to by your new is\n"
+       N_("You have created a nested tag. The object referred to by your new tag is\n"
           "already a tag. If you meant to tag the object that it points to, use:\n"
           "\n"
           "\tgit tag -f %s %s^{}");
diff --git a/cache.h b/cache.h
index fa8ede9a2d6441842f49740482bb74f6c23c1a5d..b4bb2e2c11adff0061065fa975874c7c4a2a318b 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -341,7 +341,8 @@ struct index_state {
                 initialized : 1,
                 drop_cache_tree : 1,
                 updated_workdir : 1,
-                updated_skipworktree : 1;
+                updated_skipworktree : 1,
+                fsmonitor_has_run_once : 1;
        struct hashmap name_hash;
        struct hashmap dir_hash;
        struct object_id oid;
index 52a44c690a7a38850e77eb1525e6f8c56e782369..7f6acdd803c33bc43200804ecec5d99f6d404224 100755 (executable)
@@ -12,7 +12,7 @@ case "$jobname" in
 linux-clang|linux-gcc)
        sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
        sudo apt-get -q update
-       sudo apt-get -q -y install language-pack-is git-svn apache2
+       sudo apt-get -q -y install language-pack-is libsvn-perl apache2
        case "$jobname" in
        linux-gcc)
                sudo apt-get -q -y install gcc-8
index 7bcc9bb7e0f9965a2ab3176c0416943430c6a6aa..7c5e54875fdacdf77235a077c9928f7d3bf0d001 100644 (file)
@@ -267,8 +267,10 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd,
                last_chunk_offset = chunk_offset;
        }
 
-       if (verify_commit_graph_lite(graph))
+       if (verify_commit_graph_lite(graph)) {
+               free(graph);
                return NULL;
+       }
 
        return graph;
 }
index a2f74aca6a156a203ba6dd7b435622060b6870df..9b6d2400e1107fa2a65f6ecd7d067809115930b9 100644 (file)
@@ -1714,142 +1714,10 @@ int mingw_putenv(const char *namevalue)
        return result ? 0 : -1;
 }
 
-/*
- * Note, this isn't a complete replacement for getaddrinfo. It assumes
- * that service contains a numerical port, or that it is null. It
- * does a simple search using gethostbyname, and returns one IPv4 host
- * if one was found.
- */
-static int WSAAPI getaddrinfo_stub(const char *node, const char *service,
-                                  const struct addrinfo *hints,
-                                  struct addrinfo **res)
-{
-       struct hostent *h = NULL;
-       struct addrinfo *ai;
-       struct sockaddr_in *sin;
-
-       if (node) {
-               h = gethostbyname(node);
-               if (!h)
-                       return WSAGetLastError();
-       }
-
-       ai = xmalloc(sizeof(struct addrinfo));
-       *res = ai;
-       ai->ai_flags = 0;
-       ai->ai_family = AF_INET;
-       ai->ai_socktype = hints ? hints->ai_socktype : 0;
-       switch (ai->ai_socktype) {
-       case SOCK_STREAM:
-               ai->ai_protocol = IPPROTO_TCP;
-               break;
-       case SOCK_DGRAM:
-               ai->ai_protocol = IPPROTO_UDP;
-               break;
-       default:
-               ai->ai_protocol = 0;
-               break;
-       }
-       ai->ai_addrlen = sizeof(struct sockaddr_in);
-       if (hints && (hints->ai_flags & AI_CANONNAME))
-               ai->ai_canonname = h ? xstrdup(h->h_name) : NULL;
-       else
-               ai->ai_canonname = NULL;
-
-       sin = xcalloc(1, ai->ai_addrlen);
-       sin->sin_family = AF_INET;
-       /* Note: getaddrinfo is supposed to allow service to be a string,
-        * which should be looked up using getservbyname. This is
-        * currently not implemented */
-       if (service)
-               sin->sin_port = htons(atoi(service));
-       if (h)
-               sin->sin_addr = *(struct in_addr *)h->h_addr;
-       else if (hints && (hints->ai_flags & AI_PASSIVE))
-               sin->sin_addr.s_addr = INADDR_ANY;
-       else
-               sin->sin_addr.s_addr = INADDR_LOOPBACK;
-       ai->ai_addr = (struct sockaddr *)sin;
-       ai->ai_next = NULL;
-       return 0;
-}
-
-static void WSAAPI freeaddrinfo_stub(struct addrinfo *res)
-{
-       free(res->ai_canonname);
-       free(res->ai_addr);
-       free(res);
-}
-
-static int WSAAPI getnameinfo_stub(const struct sockaddr *sa, socklen_t salen,
-                                  char *host, DWORD hostlen,
-                                  char *serv, DWORD servlen, int flags)
-{
-       const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
-       if (sa->sa_family != AF_INET)
-               return EAI_FAMILY;
-       if (!host && !serv)
-               return EAI_NONAME;
-
-       if (host && hostlen > 0) {
-               struct hostent *ent = NULL;
-               if (!(flags & NI_NUMERICHOST))
-                       ent = gethostbyaddr((const char *)&sin->sin_addr,
-                                           sizeof(sin->sin_addr), AF_INET);
-
-               if (ent)
-                       snprintf(host, hostlen, "%s", ent->h_name);
-               else if (flags & NI_NAMEREQD)
-                       return EAI_NONAME;
-               else
-                       snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr));
-       }
-
-       if (serv && servlen > 0) {
-               struct servent *ent = NULL;
-               if (!(flags & NI_NUMERICSERV))
-                       ent = getservbyport(sin->sin_port,
-                                           flags & NI_DGRAM ? "udp" : "tcp");
-
-               if (ent)
-                       snprintf(serv, servlen, "%s", ent->s_name);
-               else
-                       snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
-       }
-
-       return 0;
-}
-
-static HMODULE ipv6_dll = NULL;
-static void (WSAAPI *ipv6_freeaddrinfo)(struct addrinfo *res);
-static int (WSAAPI *ipv6_getaddrinfo)(const char *node, const char *service,
-                                     const struct addrinfo *hints,
-                                     struct addrinfo **res);
-static int (WSAAPI *ipv6_getnameinfo)(const struct sockaddr *sa, socklen_t salen,
-                                     char *host, DWORD hostlen,
-                                     char *serv, DWORD servlen, int flags);
-/*
- * gai_strerror is an inline function in the ws2tcpip.h header, so we
- * don't need to try to load that one dynamically.
- */
-
-static void socket_cleanup(void)
-{
-       WSACleanup();
-       if (ipv6_dll)
-               FreeLibrary(ipv6_dll);
-       ipv6_dll = NULL;
-       ipv6_freeaddrinfo = freeaddrinfo_stub;
-       ipv6_getaddrinfo = getaddrinfo_stub;
-       ipv6_getnameinfo = getnameinfo_stub;
-}
-
 static void ensure_socket_initialization(void)
 {
        WSADATA wsa;
        static int initialized = 0;
-       const char *libraries[] = { "ws2_32.dll", "wship6.dll", NULL };
-       const char **name;
 
        if (initialized)
                return;
@@ -1858,35 +1726,7 @@ static void ensure_socket_initialization(void)
                die("unable to initialize winsock subsystem, error %d",
                        WSAGetLastError());
 
-       for (name = libraries; *name; name++) {
-               ipv6_dll = LoadLibraryExA(*name, NULL,
-                                         LOAD_LIBRARY_SEARCH_SYSTEM32);
-               if (!ipv6_dll)
-                       continue;
-
-               ipv6_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *))
-                       GetProcAddress(ipv6_dll, "freeaddrinfo");
-               ipv6_getaddrinfo = (int (WSAAPI *)(const char *, const char *,
-                                                  const struct addrinfo *,
-                                                  struct addrinfo **))
-                       GetProcAddress(ipv6_dll, "getaddrinfo");
-               ipv6_getnameinfo = (int (WSAAPI *)(const struct sockaddr *,
-                                                  socklen_t, char *, DWORD,
-                                                  char *, DWORD, int))
-                       GetProcAddress(ipv6_dll, "getnameinfo");
-               if (!ipv6_freeaddrinfo || !ipv6_getaddrinfo || !ipv6_getnameinfo) {
-                       FreeLibrary(ipv6_dll);
-                       ipv6_dll = NULL;
-               } else
-                       break;
-       }
-       if (!ipv6_freeaddrinfo || !ipv6_getaddrinfo || !ipv6_getnameinfo) {
-               ipv6_freeaddrinfo = freeaddrinfo_stub;
-               ipv6_getaddrinfo = getaddrinfo_stub;
-               ipv6_getnameinfo = getnameinfo_stub;
-       }
-
-       atexit(socket_cleanup);
+       atexit((void(*)(void)) WSACleanup);
        initialized = 1;
 }
 
@@ -1904,24 +1744,12 @@ struct hostent *mingw_gethostbyname(const char *host)
        return gethostbyname(host);
 }
 
-void mingw_freeaddrinfo(struct addrinfo *res)
-{
-       ipv6_freeaddrinfo(res);
-}
-
+#undef getaddrinfo
 int mingw_getaddrinfo(const char *node, const char *service,
                      const struct addrinfo *hints, struct addrinfo **res)
 {
        ensure_socket_initialization();
-       return ipv6_getaddrinfo(node, service, hints, res);
-}
-
-int mingw_getnameinfo(const struct sockaddr *sa, socklen_t salen,
-                     char *host, DWORD hostlen, char *serv, DWORD servlen,
-                     int flags)
-{
-       ensure_socket_initialization();
-       return ipv6_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
+       return getaddrinfo(node, service, hints, res);
 }
 
 int mingw_socket(int domain, int type, int protocol)
index 4d73f8aa9d0d0937b1fcbe8d854485327fc3896c..593bdbffe68060e3cfd73fc8e3b2b0ffbc5faf64 100644 (file)
@@ -295,18 +295,10 @@ int mingw_gethostname(char *host, int namelen);
 struct hostent *mingw_gethostbyname(const char *host);
 #define gethostbyname mingw_gethostbyname
 
-void mingw_freeaddrinfo(struct addrinfo *res);
-#define freeaddrinfo mingw_freeaddrinfo
-
 int mingw_getaddrinfo(const char *node, const char *service,
                      const struct addrinfo *hints, struct addrinfo **res);
 #define getaddrinfo mingw_getaddrinfo
 
-int mingw_getnameinfo(const struct sockaddr *sa, socklen_t salen,
-                     char *host, DWORD hostlen, char *serv, DWORD servlen,
-                     int flags);
-#define getnameinfo mingw_getnameinfo
-
 int mingw_socket(int domain, int type, int protocol);
 #define socket mingw_socket
 
index 19ce2f296a79da9275105748cbb222a7fd50e50d..b71688eeb73f10da004f3d16e3de9afd13eb9c7e 100644 (file)
@@ -576,13 +576,21 @@ else
        ifneq ($(shell expr "$(uname_R)" : '1\.'),2)
                # MSys2
                prefix = /usr/
+               # Enable DEP
+               BASIC_LDFLAGS += -Wl,--nxcompat
+               # Enable ASLR (unless debugging)
+               ifneq (,$(findstring -O,$(filter-out -O0 -Og,$(CFLAGS))))
+                       BASIC_LDFLAGS += -Wl,--dynamicbase
+               endif
                ifeq (MINGW32,$(MSYSTEM))
                        prefix = /mingw32
                        HOST_CPU = i686
+                       BASIC_LDFLAGS += -Wl,--pic-executable,-e,_mainCRTStartup
                endif
                ifeq (MINGW64,$(MSYSTEM))
                        prefix = /mingw64
                        HOST_CPU = x86_64
+                       BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup
                else
                        COMPAT_CFLAGS += -D_USE_32BIT_TIME_T
                        BASIC_LDFLAGS += -Wl,--large-address-aware
index 536754583b59945e984ad487b6e524e5d1de7056..7440aa1c4638103c952c225f2c9b77d8c9451b08 100644 (file)
@@ -4,6 +4,11 @@ package DiffHighlight;
 use warnings FATAL => 'all';
 use strict;
 
+# Use the correct value for both UNIX and Windows (/dev/null vs nul)
+use File::Spec;
+
+my $NULL = File::Spec->devnull();
+
 # Highlight by reversing foreground and background. You could do
 # other things like bold or underline if you prefer.
 my @OLD_HIGHLIGHT = (
@@ -134,7 +139,7 @@ sub highlight_stdin {
 # fallback, which means we will work even if git can't be run.
 sub color_config {
        my ($key, $default) = @_;
-       my $s = `git config --get-color $key 2>/dev/null`;
+       my $s = `git config --get-color $key 2>$NULL`;
        return length($s) ? $s : $default;
 }
 
index 665bd2d4254b12edf38e94cb0e8b2200ae3bf34a..1dee0aded1c433c7cfb90195328f270559c9b421 100644 (file)
@@ -129,7 +129,6 @@ static void fsmonitor_refresh_callback(struct index_state *istate, const char *n
 
 void refresh_fsmonitor(struct index_state *istate)
 {
-       static int has_run_once = 0;
        struct strbuf query_result = STRBUF_INIT;
        int query_success = 0;
        size_t bol; /* beginning of line */
@@ -137,9 +136,9 @@ void refresh_fsmonitor(struct index_state *istate)
        char *buf;
        int i;
 
-       if (!core_fsmonitor || has_run_once)
+       if (!core_fsmonitor || istate->fsmonitor_has_run_once)
                return;
-       has_run_once = 1;
+       istate->fsmonitor_has_run_once = 1;
 
        trace_printf_key(&trace_fsmonitor, "refresh fsmonitor");
        /*
index d13f02da95f3b9b3921c3ccff9e3b6a7511cd666..fc00d5946af68e536876d42a1463b21924edefa5 100755 (executable)
@@ -431,6 +431,7 @@ END
 sub safe_pipe_capture {
     my @output;
     if (my $pid = open my $child, '-|') {
+       binmode($child, ":crlf");
        @output = (<$child>);
        close $child or die join(' ',@_).": $! $?";
     } else {
index 7bfb6737dfe7be46f3f29903bef844c3c2b1be11..46af3e60b7185b2767accbee3420903edaf53d6f 100755 (executable)
@@ -71,7 +71,7 @@ then
        then
                merge_tool="$GIT_DIFF_TOOL"
        else
-               merge_tool="$(get_merge_tool)" || exit
+               merge_tool="$(get_merge_tool)"
        fi
 fi
 
index aaa4eed0bc7fc2c5706853d39e4644c9d31e1e0d..204a5acd66f5444412f0088b8df6cb0ae2fd6b41 100644 (file)
@@ -80,14 +80,18 @@ show_tool_names () {
        }
 }
 
-diff_mode() {
+diff_mode () {
        test "$TOOL_MODE" = diff
 }
 
-merge_mode() {
+merge_mode () {
        test "$TOOL_MODE" = merge
 }
 
+gui_mode () {
+       test "$GIT_MERGETOOL_GUI" = true
+}
+
 translate_merge_tool_path () {
        echo "$1"
 }
@@ -351,20 +355,36 @@ guess_merge_tool () {
 }
 
 get_configured_merge_tool () {
-       # If first argument is true, find the guitool instead
-       if test "$1" = true
-       then
-               gui_prefix=gui
-       fi
-
-       # Diff mode first tries diff.(gui)tool and falls back to merge.(gui)tool.
-       # Merge mode only checks merge.(gui)tool
+       keys=
        if diff_mode
        then
-               merge_tool=$(git config diff.${gui_prefix}tool || git config merge.${gui_prefix}tool)
+               if gui_mode
+               then
+                       keys="diff.guitool merge.guitool diff.tool merge.tool"
+               else
+                       keys="diff.tool merge.tool"
+               fi
        else
-               merge_tool=$(git config merge.${gui_prefix}tool)
+               if gui_mode
+               then
+                       keys="merge.guitool merge.tool"
+               else
+                       keys="merge.tool"
+               fi
        fi
+
+       merge_tool=$(
+               IFS=' '
+               for key in $keys
+               do
+                       selected=$(git config $key)
+                       if test -n "$selected"
+                       then
+                               echo "$selected"
+                               return
+                       fi
+               done)
+
        if test -n "$merge_tool" && ! valid_tool "$merge_tool"
        then
                echo >&2 "git config option $TOOL_MODE.${gui_prefix}tool set to unknown tool: $merge_tool"
@@ -404,14 +424,17 @@ get_merge_tool_path () {
 }
 
 get_merge_tool () {
+       is_guessed=false
        # Check if a merge tool has been configured
        merge_tool=$(get_configured_merge_tool)
        # Try to guess an appropriate merge tool if no tool has been set.
        if test -z "$merge_tool"
        then
                merge_tool=$(guess_merge_tool) || exit
+               is_guessed=true
        fi
        echo "$merge_tool"
+       test "$is_guessed" = false
 }
 
 mergetool_find_win32_cmd () {
index 01b9ad59b24ff77221d5db4118c9d0265dc25fad..88fa6a914a172877991ae9890cae1a42ca51fb89 100755 (executable)
@@ -389,7 +389,7 @@ print_noop_and_exit () {
 
 main () {
        prompt=$(git config --bool mergetool.prompt)
-       gui_tool=false
+       GIT_MERGETOOL_GUI=false
        guessed_merge_tool=false
        orderfile=
 
@@ -416,10 +416,10 @@ main () {
                        esac
                        ;;
                --no-gui)
-                       gui_tool=false
+                       GIT_MERGETOOL_GUI=false
                        ;;
                -g|--gui)
-                       gui_tool=true
+                       GIT_MERGETOOL_GUI=true
                        ;;
                -y|--no-prompt)
                        prompt=false
@@ -449,12 +449,8 @@ main () {
 
        if test -z "$merge_tool"
        then
-               # Check if a merge tool has been configured
-               merge_tool=$(get_configured_merge_tool $gui_tool)
-               # Try to guess an appropriate merge tool if no tool has been set.
-               if test -z "$merge_tool"
+               if ! merge_tool=$(get_merge_tool)
                then
-                       merge_tool=$(guess_merge_tool) || exit
                        guessed_merge_tool=true
                fi
        fi
index f675a9631662ef5f6841b376e352b7b159e52e14..e36561a6db0752f12fe22883f81489d62d81a4ca 100644 (file)
@@ -526,8 +526,8 @@ static void finish_request(struct transfer_request *request)
        if (request->headers != NULL)
                curl_slist_free_all(request->headers);
 
-       /* URL is reused for MOVE after PUT */
-       if (request->state != RUN_PUT) {
+       /* URL is reused for MOVE after PUT and used during FETCH */
+       if (request->state != RUN_PUT && request->state != RUN_FETCH_PACKED) {
                FREE_AND_NULL(request->url);
        }
 
diff --git a/http.c b/http.c
index 98fb06df0b9c28f7d5fc3c1407682e9333ee6923..27aa0a3192988cd0c272dab0e9f6cf52d538b6fa 100644 (file)
--- a/http.c
+++ b/http.c
@@ -176,7 +176,7 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
        memcpy(ptr, buffer->buf.buf + buffer->posn, size);
        buffer->posn += size;
 
-       return size;
+       return size / eltsize;
 }
 
 #ifndef NO_CURL_IOCTL
@@ -204,12 +204,12 @@ size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
        struct strbuf *buffer = buffer_;
 
        strbuf_add(buffer, ptr, size);
-       return size;
+       return nmemb;
 }
 
 size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf)
 {
-       return eltsize * nmemb;
+       return nmemb;
 }
 
 static void closedown_active_slot(struct active_request_slot *slot)
@@ -2319,14 +2319,14 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
                        BUG("curl_easy_getinfo for HTTP code failed: %s",
                                curl_easy_strerror(c));
                if (slot->http_code >= 300)
-                       return size;
+                       return nmemb;
        }
 
        do {
                ssize_t retval = xwrite(freq->localfile,
                                        (char *) ptr + posn, size - posn);
                if (retval < 0)
-                       return posn;
+                       return posn / eltsize;
                posn += retval;
        } while (posn < size);
 
@@ -2339,7 +2339,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
                the_hash_algo->update_fn(&freq->c, expn,
                                         sizeof(expn) - freq->stream.avail_out);
        } while (freq->stream.avail_in && freq->zret == Z_OK);
-       return size;
+       return nmemb;
 }
 
 struct http_object_request *new_http_object_request(const char *base_url,
diff --git a/midx.c b/midx.c
index d5d2e9522fe39dc1032df4dcdea34e0eb3c741fb..e7e1fe4d65ac3be54154e44ff07cd6122011405c 100644 (file)
--- a/midx.c
+++ b/midx.c
@@ -192,18 +192,17 @@ void close_midx(struct multi_pack_index *m)
        m->fd = -1;
 
        for (i = 0; i < m->num_packs; i++) {
-               if (m->packs[i]) {
-                       close_pack(m->packs[i]);
-                       free(m->packs[i]);
-               }
+               if (m->packs[i])
+                       m->packs[i]->multi_pack_index = 0;
        }
        FREE_AND_NULL(m->packs);
        FREE_AND_NULL(m->pack_names);
 }
 
-int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
+int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id)
 {
        struct strbuf pack_name = STRBUF_INIT;
+       struct packed_git *p;
 
        if (pack_int_id >= m->num_packs)
                die(_("bad pack-int-id: %u (%u total packs)"),
@@ -215,9 +214,18 @@ int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id)
        strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir,
                    m->pack_names[pack_int_id]);
 
-       m->packs[pack_int_id] = add_packed_git(pack_name.buf, pack_name.len, m->local);
+       p = add_packed_git(pack_name.buf, pack_name.len, m->local);
        strbuf_release(&pack_name);
-       return !m->packs[pack_int_id];
+
+       if (!p)
+               return 1;
+
+       p->multi_pack_index = 1;
+       m->packs[pack_int_id] = p;
+       install_packed_git(r, p);
+       list_add_tail(&p->mru, &r->objects->packed_git_mru);
+
+       return 0;
 }
 
 int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result)
@@ -261,7 +269,10 @@ static uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos)
        return get_be32(m->chunk_object_offsets + pos * MIDX_CHUNK_OFFSET_WIDTH);
 }
 
-static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry *e, uint32_t pos)
+static int nth_midxed_pack_entry(struct repository *r,
+                                struct multi_pack_index *m,
+                                struct pack_entry *e,
+                                uint32_t pos)
 {
        uint32_t pack_int_id;
        struct packed_git *p;
@@ -271,7 +282,7 @@ static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry *
 
        pack_int_id = nth_midxed_pack_int_id(m, pos);
 
-       if (prepare_midx_pack(m, pack_int_id))
+       if (prepare_midx_pack(r, m, pack_int_id))
                die(_("error preparing packfile from multi-pack-index"));
        p = m->packs[pack_int_id];
 
@@ -301,14 +312,17 @@ static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry *
        return 1;
 }
 
-int fill_midx_entry(const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m)
+int fill_midx_entry(struct repository * r,
+                   const struct object_id *oid,
+                   struct pack_entry *e,
+                   struct multi_pack_index *m)
 {
        uint32_t pos;
 
        if (!bsearch_midx(oid, m, &pos))
                return 0;
 
-       return nth_midxed_pack_entry(m, e, pos);
+       return nth_midxed_pack_entry(r, m, e, pos);
 }
 
 /* Match "foo.idx" against either "foo.pack" _or_ "foo.idx". */
@@ -1020,7 +1034,7 @@ static int compare_pair_pos_vs_id(const void *_a, const void *_b)
                        display_progress(progress, _n); \
        } while (0)
 
-int verify_midx_file(const char *object_dir)
+int verify_midx_file(struct repository *r, const char *object_dir)
 {
        struct pair_pos_vs_id *pairs = NULL;
        uint32_t i;
@@ -1034,7 +1048,7 @@ int verify_midx_file(const char *object_dir)
        progress = start_progress(_("Looking for referenced packfiles"),
                                  m->num_packs);
        for (i = 0; i < m->num_packs; i++) {
-               if (prepare_midx_pack(m, i))
+               if (prepare_midx_pack(r, m, i))
                        midx_report("failed to load pack in position %d", i);
 
                display_progress(progress, i + 1);
@@ -1099,7 +1113,7 @@ int verify_midx_file(const char *object_dir)
 
                nth_midxed_object_oid(&oid, m, pairs[i].pos);
 
-               if (!fill_midx_entry(&oid, &e, m)) {
+               if (!fill_midx_entry(r, &oid, &e, m)) {
                        midx_report(_("failed to load pack entry for oid[%d] = %s"),
                                    pairs[i].pos, oid_to_hex(&oid));
                        continue;
diff --git a/midx.h b/midx.h
index 26dd042d6381336bfd576ab769509f674c364d08..3eb29731f2b1e8e96a116a683fd8baad1020a46b 100644 (file)
--- a/midx.h
+++ b/midx.h
@@ -5,6 +5,7 @@
 
 struct object_id;
 struct pack_entry;
+struct repository;
 
 #define GIT_TEST_MULTI_PACK_INDEX "GIT_TEST_MULTI_PACK_INDEX"
 
@@ -37,18 +38,18 @@ struct multi_pack_index {
 };
 
 struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local);
-int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id);
+int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);
 int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result);
 struct object_id *nth_midxed_object_oid(struct object_id *oid,
                                        struct multi_pack_index *m,
                                        uint32_t n);
-int fill_midx_entry(const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m);
+int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m);
 int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name);
 int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local);
 
 int write_midx_file(const char *object_dir);
 void clear_midx_file(struct repository *r);
-int verify_midx_file(const char *object_dir);
+int verify_midx_file(struct repository *r, const char *object_dir);
 
 void close_midx(struct multi_pack_index *m);
 
diff --git a/notes.h b/notes.h
index 414bc6855ad1593fb281f6a829797b34f3fb2e12..76337f2384723dbce79e437aa6aaa3ba7e9901a4 100644 (file)
--- a/notes.h
+++ b/notes.h
@@ -276,12 +276,10 @@ void init_display_notes(struct display_notes_opt *opt);
 
 /*
  * Append notes for the given 'object_sha1' from all trees set up by
- * init_display_notes() to 'sb'.  The 'flags' are a bitwise
- * combination of
+ * init_display_notes() to 'sb'.
  *
- * - NOTES_SHOW_HEADER: add a 'Notes (refname):' header
- *
- * - NOTES_INDENT: indent the notes by 4 places
+ * If 'raw' is false the note will be indented by 4 places and
+ * a 'Notes (refname):' header added.
  *
  * You *must* call init_display_notes() before using this function.
  */
index 46a1da79cc8390de89114c127c706fb020d7c82c..272e01e452b97bd8598a76d6facc5a6f803b579a 100644 (file)
@@ -76,7 +76,8 @@ struct packed_git {
                 pack_keep_in_core:1,
                 freshened:1,
                 do_not_close:1,
-                pack_promisor:1;
+                pack_promisor:1,
+                multi_pack_index:1;
        unsigned char hash[GIT_MAX_RAWSZ];
        struct revindex_entry *revindex;
        /* something like ".git/objects/pack/xxxxx.pack" */
@@ -128,12 +129,6 @@ struct raw_object_store {
        /* A most-recently-used ordered version of the packed_git list. */
        struct list_head packed_git_mru;
 
-       /*
-        * A linked list containing all packfiles, starting with those
-        * contained in the multi_pack_index.
-        */
-       struct packed_git *all_packs;
-
        /*
         * A fast, rough count of the number of objects in the repository.
         * These two fields are not meant for direct access. Use
index 9f52af928131e8bf9f72a1afccdcb0831e6daf9f..49c8544ff4591e71e1845cd1b275d5fdb898b400 100644 (file)
@@ -994,8 +994,6 @@ static void prepare_packed_git(struct repository *r)
        }
        rearrange_packed_git(r);
 
-       r->objects->all_packs = NULL;
-
        prepare_packed_git_mru(r);
        r->objects->packed_git_initialized = 1;
 }
@@ -1026,26 +1024,16 @@ struct multi_pack_index *get_multi_pack_index(struct repository *r)
 
 struct packed_git *get_all_packs(struct repository *r)
 {
-       prepare_packed_git(r);
-
-       if (!r->objects->all_packs) {
-               struct packed_git *p = r->objects->packed_git;
-               struct multi_pack_index *m;
-
-               for (m = r->objects->multi_pack_index; m; m = m->next) {
-                       uint32_t i;
-                       for (i = 0; i < m->num_packs; i++) {
-                               if (!prepare_midx_pack(m, i)) {
-                                       m->packs[i]->next = p;
-                                       p = m->packs[i];
-                               }
-                       }
-               }
+       struct multi_pack_index *m;
 
-               r->objects->all_packs = p;
+       prepare_packed_git(r);
+       for (m = r->objects->multi_pack_index; m; m = m->next) {
+               uint32_t i;
+               for (i = 0; i < m->num_packs; i++)
+                       prepare_midx_pack(r, m, i);
        }
 
-       return r->objects->all_packs;
+       return r->objects->packed_git;
 }
 
 struct list_head *get_packed_git_mru(struct repository *r)
@@ -1998,13 +1986,13 @@ int find_pack_entry(struct repository *r, const struct object_id *oid, struct pa
                return 0;
 
        for (m = r->objects->multi_pack_index; m; m = m->next) {
-               if (fill_midx_entry(oid, e, m))
+               if (fill_midx_entry(r, oid, e, m))
                        return 1;
        }
 
        list_for_each(pos, &r->objects->packed_git_mru) {
                struct packed_git *p = list_entry(pos, struct packed_git, mru);
-               if (fill_pack_entry(oid, e, p)) {
+               if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) {
                        list_move(&p->mru, &r->objects->packed_git_mru);
                        return 1;
                }
index cb24f1aa8ae980a366f6f700db15b68064e1f926..987e27cb91162ab03320ff9674f3ad52ffa829b4 100644 (file)
@@ -261,6 +261,35 @@ static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
        return PARSE_OPT_UNKNOWN;
 }
 
+static int has_string(const char *it, const char **array)
+{
+       while (*array)
+               if (!strcmp(it, *(array++)))
+                       return 1;
+       return 0;
+}
+
+static int is_alias(struct parse_opt_ctx_t *ctx,
+                   const struct option *one_opt,
+                   const struct option *another_opt)
+{
+       const char **group;
+
+       if (!ctx->alias_groups)
+               return 0;
+
+       if (!one_opt->long_name || !another_opt->long_name)
+               return 0;
+
+       for (group = ctx->alias_groups; *group; group += 3) {
+               /* it and other are from the same family? */
+               if (has_string(one_opt->long_name, group) &&
+                   has_string(another_opt->long_name, group))
+                       return 1;
+       }
+       return 0;
+}
+
 static enum parse_opt_result parse_long_opt(
        struct parse_opt_ctx_t *p, const char *arg,
        const struct option *options)
@@ -298,7 +327,8 @@ static enum parse_opt_result parse_long_opt(
                        if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN) &&
                            !strncmp(long_name, arg, arg_end - arg)) {
 is_abbreviated:
-                               if (abbrev_option) {
+                               if (abbrev_option &&
+                                   !is_alias(p, abbrev_option, options)) {
                                        /*
                                         * If this is abbreviated, it is
                                         * ambiguous. So when there is no
@@ -447,6 +477,10 @@ static void parse_options_check(const struct option *opts)
                        if (opts->callback)
                                BUG("OPTION_LOWLEVEL_CALLBACK needs no high level callback");
                        break;
+               case OPTION_ALIAS:
+                       BUG("OPT_ALIAS() should not remain at this point. "
+                           "Are you using parse_options_step() directly?\n"
+                           "That case is not supported yet.");
                default:
                        ; /* ok. (usually accepts an argument) */
                }
@@ -458,11 +492,10 @@ static void parse_options_check(const struct option *opts)
                exit(128);
 }
 
-void parse_options_start(struct parse_opt_ctx_t *ctx,
-                        int argc, const char **argv, const char *prefix,
-                        const struct option *options, int flags)
+static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
+                                 int argc, const char **argv, const char *prefix,
+                                 const struct option *options, int flags)
 {
-       memset(ctx, 0, sizeof(*ctx));
        ctx->argc = argc;
        ctx->argv = argv;
        if (!(flags & PARSE_OPT_ONE_SHOT)) {
@@ -484,6 +517,14 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
        parse_options_check(options);
 }
 
+void parse_options_start(struct parse_opt_ctx_t *ctx,
+                        int argc, const char **argv, const char *prefix,
+                        const struct option *options, int flags)
+{
+       memset(ctx, 0, sizeof(*ctx));
+       parse_options_start_1(ctx, argc, argv, prefix, options, flags);
+}
+
 static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
 {
        int printed_dashdash = 0;
@@ -575,6 +616,83 @@ static int show_gitcomp(const struct option *opts)
        return PARSE_OPT_COMPLETE;
 }
 
+/*
+ * Scan and may produce a new option[] array, which should be used
+ * instead of the original 'options'.
+ *
+ * Right now this is only used to preprocess and substitue
+ * OPTION_ALIAS.
+ */
+static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
+                                        const struct option *options)
+{
+       struct option *newopt;
+       int i, nr, alias;
+       int nr_aliases = 0;
+
+       for (nr = 0; options[nr].type != OPTION_END; nr++) {
+               if (options[nr].type == OPTION_ALIAS)
+                       nr_aliases++;
+       }
+
+       if (!nr_aliases)
+               return NULL;
+
+       ALLOC_ARRAY(newopt, nr + 1);
+       COPY_ARRAY(newopt, options, nr + 1);
+
+       /* each alias has two string pointers and NULL */
+       CALLOC_ARRAY(ctx->alias_groups, 3 * (nr_aliases + 1));
+
+       for (alias = 0, i = 0; i < nr; i++) {
+               int short_name;
+               const char *long_name;
+               const char *source;
+               int j;
+
+               if (newopt[i].type != OPTION_ALIAS)
+                       continue;
+
+               short_name = newopt[i].short_name;
+               long_name = newopt[i].long_name;
+               source = newopt[i].value;
+
+               if (!long_name)
+                       BUG("An alias must have long option name");
+
+               for (j = 0; j < nr; j++) {
+                       const char *name = options[j].long_name;
+
+                       if (!name || strcmp(name, source))
+                               continue;
+
+                       if (options[j].type == OPTION_ALIAS)
+                               BUG("No please. Nested aliases are not supported.");
+
+                       /*
+                        * NEEDSWORK: this is a bit inconsistent because
+                        * usage_with_options() on the original options[] will print
+                        * help string as "alias of %s" but "git cmd -h" will
+                        * print the original help string.
+                        */
+                       memcpy(newopt + i, options + j, sizeof(*newopt));
+                       newopt[i].short_name = short_name;
+                       newopt[i].long_name = long_name;
+                       break;
+               }
+
+               if (j == nr)
+                       BUG("could not find source option '%s' of alias '%s'",
+                           source, newopt[i].long_name);
+               ctx->alias_groups[alias * 3 + 0] = newopt[i].long_name;
+               ctx->alias_groups[alias * 3 + 1] = options[j].long_name;
+               ctx->alias_groups[alias * 3 + 2] = NULL;
+               alias++;
+       }
+
+       return newopt;
+}
+
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
                                       const char * const *,
                                       const struct option *, int, int);
@@ -714,11 +832,16 @@ int parse_options(int argc, const char **argv, const char *prefix,
                  int flags)
 {
        struct parse_opt_ctx_t ctx;
+       struct option *real_options;
 
        disallow_abbreviated_options =
                git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);
 
-       parse_options_start(&ctx, argc, argv, prefix, options, flags);
+       memset(&ctx, 0, sizeof(ctx));
+       real_options = preprocess_options(&ctx, options);
+       if (real_options)
+               options = real_options;
+       parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
        switch (parse_options_step(&ctx, options, usagestr)) {
        case PARSE_OPT_HELP:
        case PARSE_OPT_ERROR:
@@ -741,6 +864,8 @@ int parse_options(int argc, const char **argv, const char *prefix,
        }
 
        precompose_argv(argc, argv);
+       free(real_options);
+       free(ctx.alias_groups);
        return parse_options_end(&ctx);
 }
 
@@ -835,6 +960,12 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,
                        fputc('\n', outfile);
                        pad = USAGE_OPTS_WIDTH;
                }
+               if (opts->type == OPTION_ALIAS) {
+                       fprintf(outfile, "%*s", pad + USAGE_GAP, "");
+                       fprintf_ln(outfile, _("alias of --%s"),
+                                  (const char *)opts->value);
+                       continue;
+               }
                fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", _(opts->help));
        }
        fputc('\n', outfile);
index bd00cf004900c478a0dfae2f0d311d356a67b3c6..ac6ba8abf9ec7af1712486ecfe3e397359c4a67f 100644 (file)
@@ -7,6 +7,7 @@ enum parse_opt_type {
        OPTION_ARGUMENT,
        OPTION_GROUP,
        OPTION_NUMBER,
+       OPTION_ALIAS,
        /* options with no arguments */
        OPTION_BIT,
        OPTION_NEGBIT,
@@ -183,6 +184,9 @@ struct option {
          N_("no-op (backward compatibility)"),         \
          PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb }
 
+#define OPT_ALIAS(s, l, source_long_name) \
+       { OPTION_ALIAS, (s), (l), (source_long_name) }
+
 /*
  * parse_options() will filter out the processed options and leave the
  * non-option arguments in argv[]. argv0 is assumed program name and
@@ -258,6 +262,8 @@ struct parse_opt_ctx_t {
        const char *opt;
        int flags;
        const char *prefix;
+       const char **alias_groups; /* must be in groups of 3 elements! */
+       struct option *updated_options;
 };
 
 void parse_options_start(struct parse_opt_ctx_t *ctx,
@@ -286,7 +292,9 @@ int parse_opt_commit(const struct option *, const char *, int);
 int parse_opt_tertiary(const struct option *, const char *, int);
 int parse_opt_string_list(const struct option *, const char *, int);
 int parse_opt_noop_cb(const struct option *, const char *, int);
-int parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, const struct option *, const char *, int);
+enum parse_opt_result parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx,
+                                          const struct option *,
+                                          const char *, int);
 int parse_opt_passthru(const struct option *, const char *, int);
 int parse_opt_passthru_argv(const struct option *, const char *, int);
 
index c9ed780d0be02aa111786d500cd4eea2cc7ccd25..a0e87b1e81408e17b4bb8e99bc162b6e7bce4012 100644 (file)
@@ -119,7 +119,7 @@ void packet_buf_delim(struct strbuf *buf)
        strbuf_add(buf, "0001", 4);
 }
 
-void set_packet_header(char *buf, const int size)
+void set_packet_header(char *buf, int size)
 {
        static char hexchar[] = "0123456789abcdef";
 
index 4fad4e3f9ab004c85c0b2614b4d0637809d7e1b8..22e7b9944e35d257b144fe06dce2073c91d4819f 100644 (file)
@@ -2326,6 +2326,7 @@ int discard_index(struct index_state *istate)
        free_name_hash(istate);
        cache_tree_free(&(istate->cache_tree));
        istate->initialized = 0;
+       istate->fsmonitor_has_run_once = 0;
        FREE_AND_NULL(istate->cache);
        istate->cache_alloc = 0;
        discard_split_index(istate);
index 455e9fb1eaa20e781aa63e67a7ffe41525c9ac57..728e6f1f61ea4641272e59e6287b6b47bfe0c74e 100644 (file)
@@ -157,6 +157,9 @@ static void unique_in_pack(struct packed_git *p,
        uint32_t num, i, first = 0;
        const struct object_id *current = NULL;
 
+       if (p->multi_pack_index)
+               return;
+
        if (open_pack_index(p) || !p->num_objects)
                return;
 
@@ -625,6 +628,9 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
        struct object_id oid;
        const struct object_id *mad_oid;
 
+       if (p->multi_pack_index)
+               return;
+
        if (open_pack_index(p) || !p->num_objects)
                return;
 
index 16033998da4b273aebd92c84b1e1b12e4aaf7009..855827c583bc30645ba427885caa40c5b81764d2 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 16033998da4b273aebd92c84b1e1b12e4aaf7009
+Subproject commit 855827c583bc30645ba427885caa40c5b81764d2
index 5931cf25d518ac3bfc30c3b2adb8ddfc0ccbf187..9d3cf81d4d712f9dd31b86b5542c5cba0401633a 100644 (file)
@@ -93,7 +93,7 @@
 #define SHA1DC_BIGENDIAN
 
 /* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist> */
-#elif (defined(_AIX))
+#elif (defined(_AIX) || defined(__hpux))
 
 /*
  * Defines Big Endian on a whitelist of OSs that are known to be Big
index 166d64d4a2f05e76f3966080f188b864bf6bf4bb..38bfeebd881ae8930d965536a42305771b066477 100755 (executable)
@@ -27,14 +27,14 @@ sub err {
        close $f;
 }
 
+my $line = '';
 while (<>) {
        chomp;
+       $line .= $_;
        # stitch together incomplete lines (those ending with "\")
-       while (s/\\$//) {
-               $_ .= readline;
-               chomp;
-       }
+       next if $line =~ s/\\$//;
 
+       $_ = $line;
        /\bcp\s+-a/ and err 'cp -a is not portable';
        /\bsed\s+-[^efn]\s+/ and err 'sed option not portable (use only -n, -e, -f)';
        /\becho\s+-[neE]/ and err 'echo with option is not portable (use printf)';
@@ -48,6 +48,7 @@ sub err {
        /\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)';
        /^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
                err '"FOO=bar shell_func" assignment extends beyond "shell_func"';
+       $line = '';
        # this resets our $. for each file
        close ARGV if eof;
 }
index 2232b2f79ecd7524b5763716fbca5a87bed06f5d..af82db06ac59c77c181351c76fff81ebe92f38c6 100644 (file)
@@ -149,6 +149,9 @@ int cmd__parse_options(int argc, const char **argv)
                OPT_CALLBACK(0, "expect", &expect, "string",
                             "expected output in the variable dump",
                             collect_expect),
+               OPT_GROUP("Alias"),
+               OPT_STRING('A', "alias-source", &string, "string", "get a string"),
+               OPT_ALIAS('Z', "alias-target", "alias-source"),
                OPT_END(),
        };
        int i;
index d674c88ba092d60366a14eaeccc9f4bc6f32660c..7e79b555de8059fae8f47ae1d2382d14b830a4d1 100644 (file)
@@ -1,14 +1,36 @@
 #include "test-tool.h"
 #include "cache.h"
+#include "config.h"
 
 int cmd__read_cache(int argc, const char **argv)
 {
-       int i, cnt = 1;
+       int i, cnt = 1, namelen;
+       const char *name = NULL;
+
+       if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) {
+               namelen = strlen(name);
+               argc--;
+               argv++;
+       }
+
        if (argc == 2)
                cnt = strtol(argv[1], NULL, 0);
        setup_git_directory();
+       git_config(git_default_config, NULL);
        for (i = 0; i < cnt; i++) {
                read_cache();
+               if (name) {
+                       int pos;
+
+                       refresh_index(&the_index, REFRESH_QUIET,
+                                     NULL, NULL, NULL);
+                       pos = index_name_pos(&the_index, name, namelen);
+                       if (pos < 0)
+                               die("%s not in index", name);
+                       printf("%s is%s up to date\n", name,
+                              ce_uptodate(the_index.cache[pos]) ? "" : " not");
+                       write_file(name, "%d\n", i);
+               }
                discard_cache();
        }
        return 0;
index 06a81b54c75d5948b31c03152609fccb1311c12f..5c1c86c193ab79bd89212d0eefd5a114ec542f7d 100644 (file)
@@ -76,6 +76,7 @@ PassEnv GIT_VALGRIND
 PassEnv GIT_VALGRIND_OPTIONS
 PassEnv GNUPGHOME
 PassEnv ASAN_OPTIONS
+PassEnv LSAN_OPTIONS
 PassEnv GIT_TRACE
 PassEnv GIT_CONFIG_NOSYSTEM
 PassEnv GIT_TEST_SIDEBAND_ALL
index be12090c3853b8d64bb903aa92b74001d0fdd19f..c7b70e2d28ba3f8b24a3c4dfe4bb436b1f4acfa5 100644 (file)
@@ -45,7 +45,7 @@ call the aggregation script to summarize the results:
 
     $ ./p0001-rev-list.sh
     [...]
-    $ GIT_BUILD_DIR=/path/to/other/git ./p0001-rev-list.sh
+    $ ./run /path/to/other/git -- ./p0001-rev-list.sh
     [...]
     $ ./aggregate.perl . /path/to/other/git ./p0001-rev-list.sh
 
index 76dd48f8908e4f001152088845423d1e0f631727..66554d216122d26699e425b35166de460fa3821f 100755 (executable)
@@ -5,6 +5,7 @@
 use warnings;
 use Getopt::Long;
 use Git;
+use Cwd qw(realpath);
 
 sub get_times {
        my $name = shift;
@@ -98,18 +99,21 @@ sub format_size {
 while (scalar @ARGV) {
        my $arg = $ARGV[0];
        my $dir;
+       my $prefix = '';
        last if -f $arg or $arg eq "--";
        if (! -d $arg) {
                my $rev = Git::command_oneline(qw(rev-parse --verify), $arg);
                $dir = "build/".$rev;
+       } elsif ($arg eq '.') {
+               $dir = '.';
        } else {
-               $arg =~ s{/*$}{};
-               $dir = $arg;
-               $dirabbrevs{$dir} = $dir;
+               $dir = realpath($arg);
+               $dirnames{$dir} = $dir;
+               $prefix .= 'bindir';
        }
        push @dirs, $dir;
-       $dirnames{$dir} = $arg;
-       my $prefix = $dir;
+       $dirnames{$dir} ||= $arg;
+       $prefix .= $dir;
        $prefix =~ tr/^a-zA-Z0-9/_/c;
        $prefixes{$dir} = $prefix . '.';
        shift @ARGV;
@@ -311,9 +315,6 @@ sub print_codespeed_results {
                $environment = $reponame;
        } elsif (exists $ENV{GIT_PERF_REPO_NAME} and $ENV{GIT_PERF_REPO_NAME} ne "") {
                $environment = $ENV{GIT_PERF_REPO_NAME};
-       } elsif (exists $ENV{GIT_TEST_INSTALLED} and $ENV{GIT_TEST_INSTALLED} ne "") {
-               $environment = $ENV{GIT_TEST_INSTALLED};
-               $environment =~ s|/bin-wrappers$||;
        } else {
                $environment = `uname -r`;
                chomp $environment;
index 169f92eae3d419b2d9d4ccdfbde4a394cc9e15dd..b58a43ea4364a8e5a2c5b9af39b41ec9f0b94f5b 100644 (file)
 # because it will change our working directory.
 TEST_DIRECTORY=$(pwd)/..
 TEST_OUTPUT_DIRECTORY=$(pwd)
-ABSOLUTE_GIT_TEST_INSTALLED=$(
-       test -n "$GIT_TEST_INSTALLED" && cd "$GIT_TEST_INSTALLED" && pwd)
 
 TEST_NO_CREATE_REPO=t
 TEST_NO_MALLOC_CHECK=t
 
 . ../test-lib.sh
 
-if test -z "$GIT_TEST_INSTALLED"; then
-       perf_results_prefix=
-else
-       perf_results_prefix=$(printf "%s" "${GIT_TEST_INSTALLED%/bin-wrappers}" | tr -c "[a-zA-Z0-9]" "[_*]")"."
-       GIT_TEST_INSTALLED=$ABSOLUTE_GIT_TEST_INSTALLED
+if test -n "$GIT_TEST_INSTALLED" -a -z "$PERF_SET_GIT_TEST_INSTALLED"
+then
+       error "Do not use GIT_TEST_INSTALLED with the perf tests.
+
+Instead use:
+
+    ./run <path-to-git> -- <tests>
+
+See t/perf/README for details."
 fi
 
 # Variables from test-lib that are normally internal to the tests; we
@@ -179,7 +181,7 @@ test_wrapper_ () {
                base=$(basename "$0" .sh)
                echo "$test_count" >>"$perf_results_dir"/$base.subtests
                echo "$1" >"$perf_results_dir"/$base.$test_count.descr
-               base="$perf_results_dir"/"$perf_results_prefix$(basename "$0" .sh)"."$test_count"
+               base="$perf_results_dir"/"$PERF_RESULTS_PREFIX$(basename "$0" .sh)"."$test_count"
                "$test_wrapper_func_" "$@"
        fi
 
index 9aaa733c770fb97157e273b6c6d1efd38f9a630a..c7b86104e12a6637b1084d6e02743f6c36df9265 100755 (executable)
@@ -70,6 +70,24 @@ build_git_rev () {
        ) || die "failed to build revision '$mydir'"
 }
 
+set_git_test_installed () {
+       mydir=$1
+
+       mydir_abs=$(cd $mydir && pwd)
+       mydir_abs_wrappers="$mydir_abs_wrappers/bin-wrappers"
+       if test -d "$mydir_abs_wrappers"
+       then
+               GIT_TEST_INSTALLED=$mydir_abs_wrappers
+       else
+               # Older versions of git lacked bin-wrappers;
+               # fallback to the files in the root.
+               GIT_TEST_INSTALLED=$mydir_abs
+       fi
+       export GIT_TEST_INSTALLED
+       PERF_SET_GIT_TEST_INSTALLED=true
+       export PERF_SET_GIT_TEST_INSTALLED
+}
+
 run_dirs_helper () {
        mydir=${1%/}
        shift
@@ -79,7 +97,16 @@ run_dirs_helper () {
        if test $# -gt 0 -a "$1" = --; then
                shift
        fi
-       if [ ! -d "$mydir" ]; then
+
+       PERF_RESULTS_PREFIX=
+       if test "$mydir" = "."
+       then
+               unset GIT_TEST_INSTALLED
+       elif test -d "$mydir"
+       then
+               PERF_RESULTS_PREFIX=bindir$(cd $mydir && printf "%s" "$(pwd)" | tr -c "[a-zA-Z0-9]" "_").
+               set_git_test_installed "$mydir"
+       else
                rev=$(git rev-parse --verify "$mydir" 2>/dev/null) ||
                die "'$mydir' is neither a directory nor a valid revision"
                if [ ! -d build/$rev ]; then
@@ -87,16 +114,12 @@ run_dirs_helper () {
                fi
                build_git_rev $rev "$mydir"
                mydir=build/$rev
+
+               PERF_RESULTS_PREFIX=build_$rev.
+               set_git_test_installed "$mydir"
        fi
-       if test "$mydir" = .; then
-               unset GIT_TEST_INSTALLED
-       else
-               GIT_TEST_INSTALLED="$mydir/bin-wrappers"
-               # Older versions of git lacked bin-wrappers; fallback to the
-               # files in the root.
-               test -d "$GIT_TEST_INSTALLED" || GIT_TEST_INSTALLED=$mydir
-               export GIT_TEST_INSTALLED
-       fi
+       export PERF_RESULTS_PREFIX
+
        run_one_dir "$@"
 }
 
index 800b3ea5f5b64650efa95bfa05e8f90945966f85..cebc77fab0b254fc2e6f63e7eb68956b2b3dec9c 100755 (executable)
@@ -48,6 +48,12 @@ Standard options
     -q, --quiet           be quiet
     --expect <string>     expected output in the variable dump
 
+Alias
+    -A, --alias-source <string>
+                          get a string
+    -Z, --alias-target <string>
+                          get a string
+
 EOF
 
 test_expect_success 'test help' '
@@ -224,6 +230,17 @@ test_expect_success 'non ambiguous option (after two options it abbreviates)' '
        test-tool parse-options --expect="string: 123" --st 123
 '
 
+test_expect_success 'Alias options do not contribute to abbreviation' '
+       test-tool parse-options --alias-source 123 >output &&
+       grep "^string: 123" output &&
+       test-tool parse-options --alias-target 123 >output &&
+       grep "^string: 123" output &&
+       test_must_fail test-tool parse-options --alias &&
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+       test-tool parse-options --alias 123 >output &&
+       grep "^string: 123" output
+'
+
 cat >typo.err <<\EOF
 error: did you mean `--boolean` (with two dashes ?)
 EOF
index c5014ad9a63f2451f84db5076f902a0132d318c1..822381dd9df67f7a392e7697c21d9aade2eb56e1 100755 (executable)
@@ -60,38 +60,47 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'checkout -b to a new branch, set to HEAD' '
+       test_when_finished "
+               git checkout branch1 &&
+               test_might_fail git branch -D branch2" &&
        do_checkout branch2
 '
 
-test_expect_success 'checkout -b to a new branch, set to an explicit ref' '
-       git checkout branch1 &&
-       git branch -D branch2 &&
+test_expect_success 'checkout -b to a merge base' '
+       test_when_finished "
+               git checkout branch1 &&
+               test_might_fail git branch -D branch2" &&
+       git checkout -b branch2 branch1...
+'
 
+test_expect_success 'checkout -b to a new branch, set to an explicit ref' '
+       test_when_finished "
+               git checkout branch1 &&
+               test_might_fail git branch -D branch2" &&
        do_checkout branch2 $HEAD1
 '
 
 test_expect_success 'checkout -b to a new branch with unmergeable changes fails' '
-       git checkout branch1 &&
-
-       # clean up from previous test
-       git branch -D branch2 &&
-
        setup_dirty_unmergeable &&
        test_must_fail do_checkout branch2 $HEAD1 &&
        test_dirty_unmergeable
 '
 
 test_expect_success 'checkout -f -b to a new branch with unmergeable changes discards changes' '
+       test_when_finished "
+               git checkout branch1 &&
+               test_might_fail git branch -D branch2" &&
+
        # still dirty and on branch1
        do_checkout branch2 $HEAD1 "-f -b" &&
        test_must_fail test_dirty_unmergeable
 '
 
 test_expect_success 'checkout -b to a new branch preserves mergeable changes' '
-       git checkout branch1 &&
-
-       # clean up from previous test
-       git branch -D branch2 &&
+       test_when_finished "
+               git reset --hard &&
+               git checkout branch1 &&
+               test_might_fail git branch -D branch2" &&
 
        setup_dirty_mergeable &&
        do_checkout branch2 $HEAD1 &&
@@ -99,27 +108,18 @@ test_expect_success 'checkout -b to a new branch preserves mergeable changes' '
 '
 
 test_expect_success 'checkout -f -b to a new branch with mergeable changes discards changes' '
-       # clean up from previous test
-       git reset --hard &&
-
-       git checkout branch1 &&
-
-       # clean up from previous test
-       git branch -D branch2 &&
-
+       test_when_finished git reset --hard HEAD &&
        setup_dirty_mergeable &&
        do_checkout branch2 $HEAD1 "-f -b" &&
        test_must_fail test_dirty_mergeable
 '
 
 test_expect_success 'checkout -b to an existing branch fails' '
-       git reset --hard HEAD &&
-
+       test_when_finished git reset --hard HEAD &&
        test_must_fail do_checkout branch2 $HEAD2
 '
 
 test_expect_success 'checkout -b to @{-1} fails with the right branch name' '
-       git reset --hard HEAD &&
        git checkout branch1 &&
        git checkout branch2 &&
        echo  >expect "fatal: A branch named '\''branch1'\'' already exists." &&
@@ -133,6 +133,12 @@ test_expect_success 'checkout -B to an existing branch resets branch to HEAD' '
        do_checkout branch2 "" -B
 '
 
+test_expect_success 'checkout -B to a merge base' '
+       git checkout branch1 &&
+
+       git checkout -B branch2 branch1...
+'
+
 test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' '
        git checkout $(git rev-parse --verify HEAD) &&
 
@@ -160,6 +166,7 @@ test_expect_success 'checkout -f -B to an existing branch with unmergeable chang
 '
 
 test_expect_success 'checkout -B to an existing branch preserves mergeable changes' '
+       test_when_finished git reset --hard &&
        git checkout branch1 &&
 
        setup_dirty_mergeable &&
@@ -168,9 +175,6 @@ test_expect_success 'checkout -B to an existing branch preserves mergeable chang
 '
 
 test_expect_success 'checkout -f -B to an existing branch with mergeable changes discards changes' '
-       # clean up from previous test
-       git reset --hard &&
-
        git checkout branch1 &&
 
        setup_dirty_mergeable &&
index e9ad50b66dece121464f0638d5a4a1dd0280d121..e9d7084d19c9d650f43f97d1c389c7fbc4cc51d2 100755 (executable)
@@ -42,6 +42,10 @@ test_expect_success 'git branch a/b/c should create a branch' '
        git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c
 '
 
+test_expect_success 'git branch mb master... should create a branch' '
+       git branch mb master... && test_path_is_file .git/refs/heads/mb
+'
+
 test_expect_success 'git branch HEAD should fail' '
        test_must_fail git branch HEAD
 '
@@ -316,8 +320,8 @@ test_expect_success 'git branch --list -v with --abbrev' '
 test_expect_success 'git branch --column' '
        COLUMNS=81 git branch --column=column >actual &&
        cat >expected <<\EOF &&
-  a/b/c     bam       foo       l       * master    n         o/p       r
-  abc       bar       j/k       m/m       master2   o/o       q
+  a/b/c     bam       foo       l       * master    mb        o/o       q
+  abc       bar       j/k       m/m       master2   n         o/p       r
 EOF
        test_cmp expected actual
 '
@@ -339,6 +343,7 @@ test_expect_success 'git branch --column with an extremely long branch name' '
   m/m
 * master
   master2
+  mb
   n
   o/o
   o/p
@@ -356,8 +361,8 @@ test_expect_success 'git branch with column.*' '
        git config --unset column.branch &&
        git config --unset column.ui &&
        cat >expected <<\EOF &&
-  a/b/c   bam   foo   l   * master    n     o/p   r
-  abc     bar   j/k   m/m   master2   o/o   q
+  a/b/c   bam   foo   l   * master    mb   o/o   q
+  abc     bar   j/k   m/m   master2   n    o/p   r
 EOF
        test_cmp expected actual
 '
@@ -381,6 +386,7 @@ test_expect_success 'git branch -v with column.ui ignored' '
   m/m
 * master
   master2
+  mb
   n
   o/o
   o/p
index 553fe3e88e0d90bde62ec4f257bd0648f917f0b5..6e1b73ec3afcfff62ebe628cc673b236bc74e63d 100755 (executable)
@@ -51,14 +51,16 @@ test_expect_success 'am with dos files without --keep-cr' '
 
 test_expect_success 'am with dos files with --keep-cr' '
        git checkout -b dosfiles-keep-cr initial &&
-       git format-patch -k --stdout initial..master | git am --keep-cr -k -3 &&
+       git format-patch -k --stdout initial..master >output &&
+       git am --keep-cr -k -3 output &&
        git diff --exit-code master
 '
 
 test_expect_success 'am with dos files config am.keepcr' '
        git config am.keepcr 1 &&
        git checkout -b dosfiles-conf-keepcr initial &&
-       git format-patch -k --stdout initial..master | git am -k -3 &&
+       git format-patch -k --stdout initial..master >output &&
+       git am -k -3 output &&
        git diff --exit-code master
 '
 
index 217adf3a632b49e9322de1db78c3e1a588c3b7bd..b3c8a92450bc0e9ba869563ef1a7a4c1362cebd6 100755 (executable)
@@ -62,4 +62,16 @@ test_expect_success MINGW 'remote nick cannot contain backslashes' '
        test_i18ngrep ! "unable to access" err
 '
 
+test_expect_success 'unc alternates' '
+       tree="$(git rev-parse HEAD:)" &&
+       mkdir test-unc-alternate &&
+       (
+               cd test-unc-alternate &&
+               git init &&
+               test_must_fail git show $tree &&
+               echo "$UNCPATH/.git/objects" >.git/objects/info/alternates &&
+               git show $tree
+       )
+'
+
 test_done
index 7411bf7fecd89984c7256668863c9f96bb75efbf..515c6735e9cb076c9f4b5a252c48216765b5076a 100755 (executable)
@@ -181,7 +181,15 @@ test_expect_success 'background auto gc respects lock for all operations' '
        # now fake a concurrent gc that holds the lock; we can use our
        # shell pid so that it looks valid.
        hostname=$(hostname || echo unknown) &&
-       printf "$$ %s" "$hostname" >.git/gc.pid &&
+       shell_pid=$$ &&
+       if test_have_prereq MINGW && test -f /proc/$shell_pid/winpid
+       then
+               # In Git for Windows, Bash (actually, the MSYS2 runtime) has a
+               # different idea of PIDs than git.exe (actually Windows). Use
+               # the Windows PID in this case.
+               shell_pid=$(cat /proc/$shell_pid/winpid)
+       fi &&
+       printf "%d %s" "$shell_pid" "$hostname" >.git/gc.pid &&
 
        # our gc should exit zero without doing anything
        run_and_wait_for_auto_gc &&
index e285686662df781c87d59c910aa9d596eb974c34..6aeeb279a0a03614151a37f1bed8f22f4af0c4f5 100755 (executable)
@@ -1702,7 +1702,7 @@ test_expect_success '--points-at finds annotated tags of tags' '
 
 test_expect_success 'recursive tagging should give advice' '
        sed -e "s/|$//" <<-EOF >expect &&
-       hint: You have created a nested tag. The object referred to by your new is
+       hint: You have created a nested tag. The object referred to by your new tag is
        hint: already a tag. If you meant to tag the object that it points to, use:
        hint: |
        hint:   git tag -f nested annotated-v4.0^{}
index 3e0a61db2348577ed5c6cef4f844c2a26548de1d..81a375fa0ff9845cb755dd77df9921d2b71c764b 100755 (executable)
@@ -346,4 +346,12 @@ test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR'
        test_cmp before after
 '
 
+test_expect_success 'discard_index() also discards fsmonitor info' '
+       test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" &&
+       test_might_fail git update-index --refresh &&
+       test-tool read-cache --print-and-refresh=tracked 2 >actual &&
+       printf "tracked is%s up to date\n" "" " not" >expect &&
+       test_cmp expect actual
+'
+
 test_done
index a9fb971615b7f40bd17f16dcc1ce99ab2c0930ca..5b61c10a9c5402bfca8473f663076f9062a2e2a4 100755 (executable)
@@ -130,14 +130,55 @@ test_expect_success 'custom mergetool' '
        test_when_finished "git reset --hard" &&
        git checkout -b test$test_count branch1 &&
        git submodule update -N &&
-       test_must_fail git merge master >/dev/null 2>&1 &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
+       test_must_fail git merge master &&
+       ( yes "" | git mergetool both ) &&
        ( yes "" | git mergetool file1 file1 ) &&
-       ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
-       ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file2 "spaced name" ) &&
+       ( yes "" | git mergetool subdir/file3 ) &&
+       ( yes "d" | git mergetool file11 ) &&
+       ( yes "d" | git mergetool file12 ) &&
+       ( yes "l" | git mergetool submod ) &&
+       test "$(cat file1)" = "master updated" &&
+       test "$(cat file2)" = "master new" &&
+       test "$(cat subdir/file3)" = "master new sub" &&
+       test "$(cat submod/bar)" = "branch1 submodule" &&
+       git commit -m "branch1 resolved with mergetool"
+'
+
+test_expect_success 'gui mergetool' '
+       test_config merge.guitool myguitool &&
+       test_config mergetool.myguitool.cmd "(printf \"gui \" && cat \"\$REMOTE\") >\"\$MERGED\"" &&
+       test_config mergetool.myguitool.trustExitCode true &&
+       test_when_finished "git reset --hard" &&
+       git checkout -b test$test_count branch1 &&
+       git submodule update -N &&
+       test_must_fail git merge master &&
+       ( yes "" | git mergetool --gui both ) &&
+       ( yes "" | git mergetool -g file1 file1 ) &&
+       ( yes "" | git mergetool --gui file2 "spaced name" ) &&
+       ( yes "" | git mergetool --gui subdir/file3 ) &&
+       ( yes "d" | git mergetool --gui file11 ) &&
+       ( yes "d" | git mergetool --gui file12 ) &&
+       ( yes "l" | git mergetool --gui submod ) &&
+       test "$(cat file1)" = "gui master updated" &&
+       test "$(cat file2)" = "gui master new" &&
+       test "$(cat subdir/file3)" = "gui master new sub" &&
+       test "$(cat submod/bar)" = "branch1 submodule" &&
+       git commit -m "branch1 resolved with mergetool"
+'
+
+test_expect_success 'gui mergetool without merge.guitool set falls back to merge.tool' '
+       test_when_finished "git reset --hard" &&
+       git checkout -b test$test_count branch1 &&
+       git submodule update -N &&
+       test_must_fail git merge master &&
+       ( yes "" | git mergetool --gui both ) &&
+       ( yes "" | git mergetool -g file1 file1 ) &&
+       ( yes "" | git mergetool --gui file2 "spaced name" ) &&
+       ( yes "" | git mergetool --gui subdir/file3 ) &&
+       ( yes "d" | git mergetool --gui file11 ) &&
+       ( yes "d" | git mergetool --gui file12 ) &&
+       ( yes "l" | git mergetool --gui submod ) &&
        test "$(cat file1)" = "master updated" &&
        test "$(cat file2)" = "master new" &&
        test "$(cat subdir/file3)" = "master new sub" &&
@@ -153,15 +194,15 @@ test_expect_success 'mergetool crlf' '
        # test_when_finished is LIFO.)
        test_config core.autocrlf true &&
        git checkout -b test$test_count branch1 &&
-       test_must_fail git merge master >/dev/null 2>&1 &&
-       ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
-       ( yes "r" | git mergetool submod >/dev/null 2>&1 ) &&
+       test_must_fail git merge master &&
+       ( yes "" | git mergetool file1 ) &&
+       ( yes "" | git mergetool file2 ) &&
+       ( yes "" | git mergetool "spaced name" ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "" | git mergetool subdir/file3 ) &&
+       ( yes "d" | git mergetool file11 ) &&
+       ( yes "d" | git mergetool file12 ) &&
+       ( yes "r" | git mergetool submod ) &&
        test "$(printf x | cat file1 -)" = "$(printf "master updated\r\nx")" &&
        test "$(printf x | cat file2 -)" = "$(printf "master new\r\nx")" &&
        test "$(printf x | cat subdir/file3 -)" = "$(printf "master new sub\r\nx")" &&
@@ -176,8 +217,8 @@ test_expect_success 'mergetool in subdir' '
        git submodule update -N &&
        (
                cd subdir &&
-               test_must_fail git merge master >/dev/null 2>&1 &&
-               ( yes "" | git mergetool file3 >/dev/null 2>&1 ) &&
+               test_must_fail git merge master &&
+               ( yes "" | git mergetool file3 ) &&
                test "$(cat file3)" = "master new sub"
        )
 '
@@ -188,14 +229,14 @@ test_expect_success 'mergetool on file in parent dir' '
        git submodule update -N &&
        (
                cd subdir &&
-               test_must_fail git merge master >/dev/null 2>&1 &&
-               ( yes "" | git mergetool file3 >/dev/null 2>&1 ) &&
-               ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
-               ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
-               ( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
-               ( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
-               ( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
-               ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
+               test_must_fail git merge master &&
+               ( yes "" | git mergetool file3 ) &&
+               ( yes "" | git mergetool ../file1 ) &&
+               ( yes "" | git mergetool ../file2 ../spaced\ name ) &&
+               ( yes "" | git mergetool ../both ) &&
+               ( yes "d" | git mergetool ../file11 ) &&
+               ( yes "d" | git mergetool ../file12 ) &&
+               ( yes "l" | git mergetool ../submod ) &&
                test "$(cat ../file1)" = "master updated" &&
                test "$(cat ../file2)" = "master new" &&
                test "$(cat ../submod/bar)" = "branch1 submodule" &&
@@ -209,9 +250,9 @@ test_expect_success 'mergetool skips autoresolved' '
        git submodule update -N &&
        test_must_fail git merge master &&
        test -n "$(git ls-files -u)" &&
-       ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
-       ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
+       ( yes "d" | git mergetool file11 ) &&
+       ( yes "d" | git mergetool file12 ) &&
+       ( yes "l" | git mergetool submod ) &&
        output="$(git mergetool --no-prompt)" &&
        test "$output" = "No files need merging"
 '
@@ -259,9 +300,9 @@ test_expect_success 'mergetool skips resolved paths when rerere is active' '
        rm -rf .git/rr-cache &&
        git checkout -b test$test_count branch1 &&
        git submodule update -N &&
-       test_must_fail git merge master >/dev/null 2>&1 &&
-       ( yes "l" | git mergetool --no-prompt submod >/dev/null 2>&1 ) &&
-       ( yes "d" "d" | git mergetool --no-prompt >/dev/null 2>&1 ) &&
+       test_must_fail git merge master &&
+       ( yes "l" | git mergetool --no-prompt submod ) &&
+       ( yes "d" "d" | git mergetool --no-prompt ) &&
        git submodule update -N &&
        output="$(yes "n" | git mergetool --no-prompt)" &&
        test "$output" = "No files need merging"
@@ -369,9 +410,9 @@ test_expect_success 'deleted vs modified submodule' '
        git checkout -b test$test_count.a test$test_count &&
        test_must_fail git merge master &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "r" | git mergetool submod ) &&
        rmdir submod && mv submod-movedaside submod &&
        test "$(cat submod/bar)" = "branch1 submodule" &&
@@ -386,9 +427,9 @@ test_expect_success 'deleted vs modified submodule' '
        git submodule update -N &&
        test_must_fail git merge master &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "l" | git mergetool submod ) &&
        test ! -e submod &&
        output="$(git mergetool --no-prompt)" &&
@@ -400,9 +441,9 @@ test_expect_success 'deleted vs modified submodule' '
        git submodule update -N &&
        test_must_fail git merge test$test_count &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "r" | git mergetool submod ) &&
        test ! -e submod &&
        test -d submod.orig &&
@@ -416,9 +457,9 @@ test_expect_success 'deleted vs modified submodule' '
        git submodule update -N &&
        test_must_fail git merge test$test_count &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "l" | git mergetool submod ) &&
        test "$(cat submod/bar)" = "master submodule" &&
        git submodule update -N &&
@@ -440,9 +481,9 @@ test_expect_success 'file vs modified submodule' '
        git checkout -b test$test_count.a branch1 &&
        test_must_fail git merge master &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "r" | git mergetool submod ) &&
        rmdir submod && mv submod-movedaside submod &&
        test "$(cat submod/bar)" = "branch1 submodule" &&
@@ -456,9 +497,9 @@ test_expect_success 'file vs modified submodule' '
        git checkout -b test$test_count.b test$test_count &&
        test_must_fail git merge master &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "l" | git mergetool submod ) &&
        git submodule update -N &&
        test "$(cat submod)" = "not a submodule" &&
@@ -472,9 +513,9 @@ test_expect_success 'file vs modified submodule' '
        git submodule update -N &&
        test_must_fail git merge test$test_count &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "r" | git mergetool submod ) &&
        test -d submod.orig &&
        git submodule update -N &&
@@ -488,9 +529,9 @@ test_expect_success 'file vs modified submodule' '
        git submodule update -N &&
        test_must_fail git merge test$test_count &&
        test -n "$(git ls-files -u)" &&
-       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
-       ( yes "" | git mergetool both>/dev/null 2>&1 ) &&
-       ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+       ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) &&
+       ( yes "" | git mergetool both ) &&
+       ( yes "d" | git mergetool file11 file12 ) &&
        ( yes "l" | git mergetool submod ) &&
        test "$(cat submod/bar)" = "master submodule" &&
        git submodule update -N &&
@@ -543,7 +584,7 @@ test_expect_success 'submodule in subdirectory' '
        git add subdir/subdir_module &&
        git commit -m "change submodule in subdirectory on test$test_count.b" &&
 
-       test_must_fail git merge test$test_count.a >/dev/null 2>&1 &&
+       test_must_fail git merge test$test_count.a &&
        (
                cd subdir &&
                ( yes "l" | git mergetool subdir_module )
@@ -554,7 +595,7 @@ test_expect_success 'submodule in subdirectory' '
        git reset --hard &&
        git submodule update -N &&
 
-       test_must_fail git merge test$test_count.a >/dev/null 2>&1 &&
+       test_must_fail git merge test$test_count.a &&
        ( yes "r" | git mergetool subdir/subdir_module ) &&
        test "$(cat subdir/subdir_module/file15)" = "test$test_count.b" &&
        git submodule update -N &&
@@ -641,7 +682,7 @@ test_expect_success 'filenames seen by tools start with ./' '
        test_config mergetool.myecho.trustExitCode true &&
        test_must_fail git merge master &&
        git mergetool --no-prompt --tool myecho -- both >actual &&
-       grep ^\./both_LOCAL_ actual >/dev/null
+       grep ^\./both_LOCAL_ actual
 '
 
 test_lazy_prereq MKTEMP '
@@ -658,8 +699,8 @@ test_expect_success MKTEMP 'temporary filenames are used with mergetool.writeToT
        test_config mergetool.myecho.trustExitCode true &&
        test_must_fail git merge master &&
        git mergetool --no-prompt --tool myecho -- both >actual &&
-       ! grep ^\./both_LOCAL_ actual >/dev/null &&
-       grep /both_LOCAL_ actual >/dev/null
+       ! grep ^\./both_LOCAL_ actual &&
+       grep /both_LOCAL_ actual
 '
 
 test_expect_success 'diff.orderFile configuration is honored' '
index 480dd0633fd3e979aecca82784d38642232d44b4..6bac9ed180e7342b34401b2d6af9e83b4472f08d 100755 (executable)
@@ -279,11 +279,27 @@ test_expect_success 'difftool + mergetool config variables' '
        echo branch >expect &&
        git difftool --no-prompt branch >actual &&
        test_cmp expect actual &&
+       git difftool --gui --no-prompt branch >actual &&
+       test_cmp expect actual &&
 
        # set merge.tool to something bogus, diff.tool to test-tool
        test_config merge.tool bogus-tool &&
        test_config diff.tool test-tool &&
        git difftool --no-prompt branch >actual &&
+       test_cmp expect actual &&
+       git difftool --gui --no-prompt branch >actual &&
+       test_cmp expect actual &&
+
+       # set merge.tool, diff.tool to something bogus, merge.guitool to test-tool
+       test_config diff.tool bogus-tool &&
+       test_config merge.guitool test-tool &&
+       git difftool --gui --no-prompt branch >actual &&
+       test_cmp expect actual &&
+
+       # set merge.tool, diff.tool, merge.guitool to something bogus, diff.guitool to test-tool
+       test_config merge.guitool bogus-tool &&
+       test_config diff.guitool test-tool &&
+       git difftool --gui --no-prompt branch >actual &&
        test_cmp expect actual
 '
 
@@ -715,4 +731,12 @@ test_expect_success 'outside worktree' '
        test_cmp expect actual
 '
 
+test_expect_success 'difftool --gui, --tool and --extcmd are mutually exclusive' '
+       difftool_test_setup &&
+       test_must_fail git difftool --gui --tool=test-tool &&
+       test_must_fail git difftool --gui --extcmd=cat &&
+       test_must_fail git difftool --tool=test-tool --extcmd=cat &&
+       test_must_fail git difftool --gui --tool=test-tool --extcmd=cat
+'
+
 test_done
index 908ddb9c46630d8d9678f610cfde7617bc38514c..599fd70e141c7b7252b65ae6603486691864974b 100644 (file)
@@ -1522,7 +1522,7 @@ test_lazy_prereq NOT_ROOT '
 '
 
 test_lazy_prereq JGIT '
-       type jgit
+       jgit --version
 '
 
 # SANITY is about "can you correctly predict what the filesystem would
index d2ea5eb20d90557de4dc979d98a9479e0c2e7d9b..24298913c0d7932e20f4677d3b8a4ea62ed69f8d 100644 (file)
@@ -1069,6 +1069,8 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
                allow_ref_in_want = git_config_bool(var, value);
        } else if (!strcmp("uploadpack.allowsidebandall", var)) {
                allow_sideband_all = git_config_bool(var, value);
+       } else if (!strcmp("core.precomposeunicode", var)) {
+               precomposed_unicode = git_config_bool(var, value);
        }
 
        if (current_config_scope() != CONFIG_SCOPE_REPO) {
index e065558c312eefb4c3d5f8bf91dd8358069e0faa..d2a1bec226ba0dfef9e3ddd96c0b3a83ea6884bb 100644 (file)
@@ -1215,7 +1215,9 @@ static void abbrev_sha1_in_line(struct strbuf *line)
        int i;
 
        if (starts_with(line->buf, "exec ") ||
-           starts_with(line->buf, "x "))
+           starts_with(line->buf, "x ") ||
+           starts_with(line->buf, "label ") ||
+           starts_with(line->buf, "l "))
                return;
 
        split = strbuf_split_max(line, ' ', 3);