aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-branch.txt6
-rw-r--r--Documentation/git-checkout.txt4
-rw-r--r--Documentation/git-difftool.txt4
-rw-r--r--Documentation/git-mergetool--lib.txt4
-rw-r--r--Documentation/git-mergetool.txt4
-rw-r--r--Documentation/git.txt21
-rw-r--r--Makefile19
-rw-r--r--branch.c2
-rw-r--r--builtin/clone.c5
-rw-r--r--builtin/difftool.c13
-rw-r--r--builtin/multi-pack-index.c2
-rw-r--r--builtin/pack-objects.c2
-rw-r--r--builtin/pack-refs.c2
-rw-r--r--builtin/show-ref.c3
-rw-r--r--builtin/submodule--helper.c2
-rw-r--r--builtin/tag.c2
-rw-r--r--cache.h3
-rwxr-xr-xci/install-dependencies.sh2
-rw-r--r--commit-graph.c4
-rw-r--r--compat/mingw.c178
-rw-r--r--compat/mingw.h8
-rw-r--r--config.mak.uname8
-rw-r--r--contrib/diff-highlight/DiffHighlight.pm7
-rw-r--r--fsmonitor.c5
-rwxr-xr-xgit-cvsexportcommit.perl1
-rwxr-xr-xgit-difftool--helper.sh2
-rw-r--r--git-mergetool--lib.sh47
-rwxr-xr-xgit-mergetool.sh12
-rw-r--r--http.c12
-rw-r--r--midx.c42
-rw-r--r--midx.h7
-rw-r--r--notes.h8
-rw-r--r--object-store.h9
-rw-r--r--packfile.c30
-rw-r--r--parse-options.c143
-rw-r--r--parse-options.h6
-rw-r--r--read-cache.c1
-rw-r--r--sha1-name.c6
m---------sha1collisiondetection0
-rw-r--r--sha1dc/sha1.c2
-rwxr-xr-xt/check-non-portable-shell.pl9
-rw-r--r--t/helper/test-parse-options.c3
-rw-r--r--t/helper/test-read-cache.c24
-rw-r--r--t/lib-httpd/apache.conf1
-rw-r--r--t/perf/README2
-rwxr-xr-xt/perf/aggregate.perl17
-rw-r--r--t/perf/perf-lib.sh18
-rwxr-xr-xt/perf/run43
-rwxr-xr-xt/t0040-parse-options.sh17
-rwxr-xr-xt/t2018-checkout-branch.sh56
-rwxr-xr-xt/t3200-branch.sh14
-rwxr-xr-xt/t4253-am-keep-cr-dos.sh6
-rwxr-xr-xt/t5580-clone-push-unc.sh12
-rwxr-xr-xt/t6500-gc.sh10
-rwxr-xr-xt/t7004-tag.sh2
-rwxr-xr-xt/t7519-status-fsmonitor.sh8
-rwxr-xr-xt/t7610-mergetool.sh163
-rwxr-xr-xt/t7800-difftool.sh24
-rw-r--r--upload-pack.c2
-rw-r--r--wt-status.c4
60 files changed, 643 insertions, 430 deletions
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 0cd87ddeff2..6ebd512b4f3 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -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
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 877e5f503a6..964f912d29e 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -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,
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 96c26e6aa82..484c485fd06 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -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.
diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt
index 055550b2bcc..4da9d240962 100644
--- a/Documentation/git-mergetool--lib.txt
+++ b/Documentation/git-mergetool--lib.txt
@@ -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.
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index 0c7975a0507..6b14702e784 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -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
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 6d1f2fd9ae9..72adfcc5e24 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -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
diff --git a/Makefile b/Makefile
index f965509b3c0..8a7e2353520 100644
--- 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; \
diff --git a/branch.c b/branch.c
index 643694542a5..a594cc23e25 100644
--- 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);
diff --git a/builtin/clone.c b/builtin/clone.c
index ffdd94e8f66..85b0d3155de 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -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)"." },
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 04ffa1d943d..53188df7143 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -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);
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index ae6e476ad56..72dfd3dadc7 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -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]);
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 9f424aababe..41d7fc59830 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -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;
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index f3353564f99..cfbd5c36c76 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -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);
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 6a706c02a6f..6456da70cc2 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -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);
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 8c72ea864c8..0bf4aa088e0 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -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 */
diff --git a/builtin/tag.c b/builtin/tag.c
index 1debd3a11c2..ef37dccf864 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -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 fa8ede9a2d6..b4bb2e2c11a 100644
--- 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;
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index 52a44c690a7..7f6acdd803c 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -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
diff --git a/commit-graph.c b/commit-graph.c
index 7bcc9bb7e0f..7c5e54875fd 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -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;
}
diff --git a/compat/mingw.c b/compat/mingw.c
index a2f74aca6a1..9b6d2400e11 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -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)
diff --git a/compat/mingw.h b/compat/mingw.h
index 4d73f8aa9d0..593bdbffe68 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -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
diff --git a/config.mak.uname b/config.mak.uname
index 19ce2f296a7..b71688eeb73 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -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
diff --git a/contrib/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm
index 536754583b5..7440aa1c463 100644
--- a/contrib/diff-highlight/DiffHighlight.pm
+++ b/contrib/diff-highlight/DiffHighlight.pm
@@ -4,6 +4,11 @@ use 5.008;
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;
}
diff --git a/fsmonitor.c b/fsmonitor.c
index 665bd2d4254..1dee0aded1c 100644
--- a/fsmonitor.c
+++ b/fsmonitor.c
@@ -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");
/*
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index d13f02da95f..fc00d5946af 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -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 {
diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index 7bfb6737dfe..46af3e60b71 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -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
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index aaa4eed0bc7..204a5acd66f 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -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 () {
diff --git a/git-mergetool.sh b/git-mergetool.sh
index 01b9ad59b24..88fa6a914a1 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -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
diff --git a/http.c b/http.c
index 98fb06df0b9..27aa0a31929 100644
--- 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 d5d2e9522fe..e7e1fe4d65a 100644
--- 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 26dd042d638..3eb29731f2b 100644
--- 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 414bc6855ad..76337f23847 100644
--- 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.
*/
diff --git a/object-store.h b/object-store.h
index 46a1da79cc8..272e01e452b 100644
--- a/object-store.h
+++ b/object-store.h
@@ -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" */
@@ -129,12 +130,6 @@ struct raw_object_store {
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
* approximate_object_count() instead.
diff --git a/packfile.c b/packfile.c
index 9f52af92813..49c8544ff45 100644
--- a/packfile.c
+++ b/packfile.c
@@ -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;
}
diff --git a/parse-options.c b/parse-options.c
index cb24f1aa8ae..987e27cb911 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -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 @@ again:
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);
diff --git a/parse-options.h b/parse-options.h
index cd756833a99..ac6ba8abf9e 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -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,
diff --git a/read-cache.c b/read-cache.c
index 4fad4e3f9ab..22e7b9944e3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -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);
diff --git a/sha1-name.c b/sha1-name.c
index 775a73d8adf..b4f5cadae74 100644
--- a/sha1-name.c
+++ b/sha1-name.c
@@ -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;
diff --git a/sha1collisiondetection b/sha1collisiondetection
-Subproject 16033998da4b273aebd92c84b1e1b12e4aaf700
+Subproject 855827c583bc30645ba427885caa40c5b81764d
diff --git a/sha1dc/sha1.c b/sha1dc/sha1.c
index 5931cf25d51..9d3cf81d4d7 100644
--- a/sha1dc/sha1.c
+++ b/sha1dc/sha1.c
@@ -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
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index 166d64d4a2f..38bfeebd881 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -27,14 +27,14 @@ for my $i (@ARGV) {
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 @@ while (<>) {
/\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;
}
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index 2232b2f79ec..af82db06ac5 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -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;
diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c
index d674c88ba09..7e79b555de8 100644
--- a/t/helper/test-read-cache.c
+++ b/t/helper/test-read-cache.c
@@ -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;
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 06a81b54c75..5c1c86c193a 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -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
diff --git a/t/perf/README b/t/perf/README
index be12090c385..c7b70e2d28b 100644
--- a/t/perf/README
+++ b/t/perf/README
@@ -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
diff --git a/t/perf/aggregate.perl b/t/perf/aggregate.perl
index 76dd48f8908..66554d21612 100755
--- a/t/perf/aggregate.perl
+++ b/t/perf/aggregate.perl
@@ -5,6 +5,7 @@ use strict;
use warnings;
use Getopt::Long;
use Git;
+use Cwd qw(realpath);
sub get_times {
my $name = shift;
@@ -98,18 +99,21 @@ usage() unless $rc;
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;
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index 169f92eae3d..b58a43ea436 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -21,19 +21,21 @@
# 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
diff --git a/t/perf/run b/t/perf/run
index 9aaa733c770..c7b86104e12 100755
--- a/t/perf/run
+++ b/t/perf/run
@@ -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 "$@"
}
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 800b3ea5f5b..cebc77fab0b 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -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
diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index c5014ad9a63..822381dd9df 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -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 &&
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index e9ad50b66de..e9d7084d19c 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -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
diff --git a/t/t4253-am-keep-cr-dos.sh b/t/t4253-am-keep-cr-dos.sh
index 553fe3e88e0..6e1b73ec3af 100755
--- a/t/t4253-am-keep-cr-dos.sh
+++ b/t/t4253-am-keep-cr-dos.sh
@@ -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
'
diff --git a/t/t5580-clone-push-unc.sh b/t/t5580-clone-push-unc.sh
index 217adf3a632..b3c8a92450b 100755
--- a/t/t5580-clone-push-unc.sh
+++ b/t/t5580-clone-push-unc.sh
@@ -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
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index 7411bf7fecd..515c6735e9c 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -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 &&
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index e285686662d..6aeeb279a0a 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -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^{}
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 3e0a61db234..81a375fa0ff 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -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
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index a9fb971615b..5b61c10a9c5 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -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' '
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 480dd0633fd..6bac9ed180e 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -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
diff --git a/upload-pack.c b/upload-pack.c
index d2ea5eb20d9..24298913c0d 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -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) {
diff --git a/wt-status.c b/wt-status.c
index e065558c312..d2a1bec226b 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -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);