diff options
-rw-r--r-- | .travis.yml | 21 | ||||
-rw-r--r-- | Documentation/RelNotes/2.12.1.txt | 41 | ||||
-rw-r--r-- | Documentation/git.txt | 3 | ||||
-rw-r--r-- | Documentation/gitdiffcore.txt | 10 | ||||
-rwxr-xr-x | GIT-VERSION-GEN | 2 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | README.md | 6 | ||||
l--------- | RelNotes | 2 | ||||
-rw-r--r-- | abspath.c | 4 | ||||
-rw-r--r-- | bisect.c | 9 | ||||
-rw-r--r-- | builtin/init-db.c | 6 | ||||
-rw-r--r-- | cache.h | 5 | ||||
-rwxr-xr-x | ci/run-linux32-build.sh | 30 | ||||
-rw-r--r-- | config.mak.uname | 18 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | diff.c | 19 | ||||
-rw-r--r-- | dir.c | 4 | ||||
-rw-r--r-- | environment.c | 2 | ||||
-rw-r--r-- | ewah/ewah_io.c | 4 | ||||
-rwxr-xr-x | git-add--interactive.perl | 8 | ||||
-rw-r--r-- | git-compat-util.h | 5 | ||||
-rw-r--r-- | http-walker.c | 11 | ||||
-rw-r--r-- | http.c | 53 | ||||
-rw-r--r-- | line-log.c | 18 | ||||
-rw-r--r-- | progress.c | 11 | ||||
-rw-r--r-- | setup.c | 4 | ||||
-rw-r--r-- | submodule.c | 10 | ||||
-rw-r--r-- | t/lib-httpd/apache.conf | 9 | ||||
-rwxr-xr-x | t/t1501-work-tree.sh | 8 | ||||
-rwxr-xr-x | t/t3701-add-interactive.sh | 18 | ||||
-rwxr-xr-x | t/t4035-diff-quiet.sh | 9 | ||||
-rwxr-xr-x | t/t4211-line-log.sh | 10 | ||||
-rwxr-xr-x | t/t5550-http-fetch-dumb.sh | 9 | ||||
-rw-r--r-- | transport.c | 2 | ||||
-rw-r--r-- | worktree.c | 2 | ||||
-rw-r--r-- | wrapper.c | 24 | ||||
-rw-r--r-- | wt-status.c | 8 |
37 files changed, 287 insertions, 129 deletions
diff --git a/.travis.yml b/.travis.yml index 9c63c8c3f6..591cc57b80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,27 @@ env: matrix: include: + - env: Linux32 + os: linux + services: + - docker + before_install: + - docker pull daald/ubuntu32:xenial + before_script: + script: + - > + docker run + --interactive + --env DEFAULT_TEST_TARGET + --env GIT_PROVE_OPTS + --env GIT_TEST_OPTS + --env GIT_TEST_CLONE_2GB + --volume "${PWD}:/usr/src/git" + daald/ubuntu32:xenial + /usr/src/git/ci/run-linux32-build.sh $(id -u $USER) + # Use the following command to debug the docker build locally: + # $ docker run -itv "${PWD}:/usr/src/git" --entrypoint /bin/bash daald/ubuntu32:xenial + # root@container:/# /usr/src/git/ci/run-linux32-build.sh - env: Documentation os: linux compiler: clang diff --git a/Documentation/RelNotes/2.12.1.txt b/Documentation/RelNotes/2.12.1.txt new file mode 100644 index 0000000000..a74f7db747 --- /dev/null +++ b/Documentation/RelNotes/2.12.1.txt @@ -0,0 +1,41 @@ +Git v2.12.1 Release Notes +========================= + +Fixes since v2.12 +----------------- + + * Reduce authentication round-trip over HTTP when the server supports + just a single authentication method. This also improves the + behaviour when Git is misconfigured to enable http.emptyAuth + against a server that does not authenticate without a username + (i.e. not using Kerberos etc., which makes http.emptyAuth + pointless). + + * Windows port wants to use OpenSSL's implementation of SHA-1 + routines, so let them. + + * Add 32-bit Linux variant to the set of platforms to be tested with + Travis CI. + + * When a redirected http transport gets an error during the + redirected request, we ignored the error we got from the server, + and ended up giving a not-so-useful error message. + + * The patch subcommand of "git add -i" was meant to have paths + selection prompt just like other subcommand, unlike "git add -p" + directly jumps to hunk selection. Recently, this was broken and + "add -i" lost the paths selection dialog, but it now has been + fixed. + + * Git v2.12 was shipped with an embarrassing breakage where various + operations that verify paths given from the user stopped dying when + seeing an issue, and instead later triggering segfault. + + * The code to parse "git log -L..." command line was buggy when there + are many ranges specified with -L; overrun of the allocated buffer + has been fixed. + + * The command-line parsing of "git log -L" copied internal data + structures using incorrect size on ILP32 systems. + +Also contains various documentation updates and code clean-ups. diff --git a/Documentation/git.txt b/Documentation/git.txt index aa895da4a5..25560f69ff 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -44,9 +44,10 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v2.12.0/git.html[documentation for release 2.12.0] +* link:v2.12.1/git.html[documentation for release 2.12.1] * release notes for + link:RelNotes/2.12.1.txt[2.12.1]. link:RelNotes/2.12.0.txt[2.12]. * link:v2.11.1/git.html[documentation for release 2.11.1] diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt index 46bc6d077c..c0a60f3158 100644 --- a/Documentation/gitdiffcore.txt +++ b/Documentation/gitdiffcore.txt @@ -84,8 +84,8 @@ format sections of the manual for 'git diff-{asterisk}' commands) or diff-patch format. -diffcore-break: For Splitting Up "Complete Rewrites" ----------------------------------------------------- +diffcore-break: For Splitting Up Complete Rewrites +-------------------------------------------------- The second transformation in the chain is diffcore-break, and is controlled by the -B option to the 'git diff-{asterisk}' commands. This is @@ -119,7 +119,7 @@ the original is used), and can be customized by giving a number after "-B" option (e.g. "-B75" to tell it to use 75%). -diffcore-rename: For Detection Renames and Copies +diffcore-rename: For Detecting Renames and Copies ------------------------------------------------- This transformation is used to detect renames and copies, and is @@ -177,8 +177,8 @@ the expense of making it slower. Without `--find-copies-harder`, copied happened to have been modified in the same changeset. -diffcore-merge-broken: For Putting "Complete Rewrites" Back Together --------------------------------------------------------------------- +diffcore-merge-broken: For Putting Complete Rewrites Back Together +------------------------------------------------------------------ This transformation is used to merge filepairs broken by diffcore-break, and not transformed into rename/copy by diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 6a208e92bf..d18eb6d9b1 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.12.0 +DEF_VER=v2.12.1 LF=' ' @@ -102,8 +102,6 @@ all:: # # Define MKDIR_WO_TRAILING_SLASH if your mkdir() can't deal with trailing slash. # -# Define NO_MKSTEMPS if you don't have mkstemps in the C library. -# # Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd # in the C library. # @@ -1280,9 +1278,6 @@ ifdef MKDIR_WO_TRAILING_SLASH COMPAT_CFLAGS += -DMKDIR_WO_TRAILING_SLASH COMPAT_OBJS += compat/mkdir.o endif -ifdef NO_MKSTEMPS - COMPAT_CFLAGS += -DNO_MKSTEMPS -endif ifdef NO_UNSETENV COMPAT_CFLAGS += -DNO_UNSETENV COMPAT_OBJS += compat/unsetenv.o @@ -12,7 +12,7 @@ Torvalds with help of a group of hackers around the net. Please read the file [INSTALL][] for installation instructions. -Many Git online resources are accessible from http://git-scm.com/ +Many Git online resources are accessible from <https://git-scm.com/> including full documentation and Git related tools. See [Documentation/gittutorial.txt][] to get started, then see @@ -33,8 +33,8 @@ requests, comments and patches to git@vger.kernel.org (read [Documentation/SubmittingPatches][] for instructions on patch submission). To subscribe to the list, send an email with just "subscribe git" in the body to majordomo@vger.kernel.org. The mailing list archives are -available at https://public-inbox.org/git, -http://marc.info/?l=git and other archival sites. +available at <https://public-inbox.org/git/>, +<http://marc.info/?l=git> and other archival sites. The maintainer frequently sends the "What's cooking" reports that list the current status of various development topics to the mailing @@ -1 +1 @@ -Documentation/RelNotes/2.12.0.txt
\ No newline at end of file +Documentation/RelNotes/2.12.1.txt
\ No newline at end of file @@ -214,12 +214,12 @@ const char *real_path_if_valid(const char *path) return strbuf_realpath(&realpath, path, 0); } -char *real_pathdup(const char *path) +char *real_pathdup(const char *path, int die_on_error) { struct strbuf realpath = STRBUF_INIT; char *retval = NULL; - if (strbuf_realpath(&realpath, path, 0)) + if (strbuf_realpath(&realpath, path, die_on_error)) retval = strbuf_detach(&realpath, NULL); strbuf_release(&realpath); @@ -940,7 +940,7 @@ int bisect_next_all(const char *prefix, int no_checkout) struct commit_list *tried; int reaches = 0, all = 0, nr, steps; const unsigned char *bisect_rev; - char steps_msg[32]; + char *steps_msg; read_bisect_terms(&term_bad, &term_good); if (read_bisect_refs()) @@ -990,14 +990,15 @@ int bisect_next_all(const char *prefix, int no_checkout) nr = all - reaches - 1; steps = estimate_bisect_steps(all); - xsnprintf(steps_msg, sizeof(steps_msg), - Q_("(roughly %d step)", "(roughly %d steps)", steps), - steps); + + steps_msg = xstrfmt(Q_("(roughly %d step)", "(roughly %d steps)", + steps), steps); /* TRANSLATORS: the last %s will be replaced with "(roughly %d steps)" translation */ printf(Q_("Bisecting: %d revision left to test after this %s\n", "Bisecting: %d revisions left to test after this %s\n", nr), nr, steps_msg); + free(steps_msg); return bisect_checkout(bisect_rev, no_checkout); } diff --git a/builtin/init-db.c b/builtin/init-db.c index 1d4d6a0078..8a6acb0ec6 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -338,7 +338,7 @@ int init_db(const char *git_dir, const char *real_git_dir, { int reinit; int exist_ok = flags & INIT_DB_EXIST_OK; - char *original_git_dir = real_pathdup(git_dir); + char *original_git_dir = real_pathdup(git_dir, 1); if (real_git_dir) { struct stat st; @@ -489,7 +489,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); if (real_git_dir && !is_absolute_path(real_git_dir)) - real_git_dir = real_pathdup(real_git_dir); + real_git_dir = real_pathdup(real_git_dir, 1); if (argc == 1) { int mkdir_tried = 0; @@ -560,7 +560,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) const char *git_dir_parent = strrchr(git_dir, '/'); if (git_dir_parent) { char *rel = xstrndup(git_dir, git_dir_parent - git_dir); - git_work_tree_cfg = real_pathdup(rel); + git_work_tree_cfg = real_pathdup(rel, 1); free(rel); } if (!git_work_tree_cfg) @@ -1045,9 +1045,6 @@ static inline int is_empty_tree_oid(const struct object_id *oid) return !hashcmp(oid->hash, EMPTY_TREE_SHA1_BIN); } - -int git_mkstemp(char *path, size_t n, const char *template); - /* set default permissions by passing mode arguments to open(2) */ int git_mkstemps_mode(char *pattern, int suffix_len, int mode); int git_mkstemp_mode(char *pattern, int mode); @@ -1109,7 +1106,7 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path, int die_on_error); const char *real_path(const char *path); const char *real_path_if_valid(const char *path); -char *real_pathdup(const char *path); +char *real_pathdup(const char *path, int die_on_error); const char *absolute_path(const char *path); char *absolute_pathdup(const char *path); const char *remove_leading_path(const char *in, const char *prefix); diff --git a/ci/run-linux32-build.sh b/ci/run-linux32-build.sh new file mode 100755 index 0000000000..e30fb2cddc --- /dev/null +++ b/ci/run-linux32-build.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Build and test Git in a 32-bit environment +# +# Usage: +# run-linux32-build.sh [host-user-id] +# + +# Update packages to the latest available versions +linux32 --32bit i386 sh -c ' + apt update >/dev/null && + apt install -y build-essential libcurl4-openssl-dev libssl-dev \ + libexpat-dev gettext python >/dev/null +' && + +# If this script runs inside a docker container, then all commands are +# usually executed as root. Consequently, the host user might not be +# able to access the test output files. +# If a host user id is given, then create a user "ci" with the host user +# id to make everything accessible to the host user. +HOST_UID=$1 && +CI_USER=$USER && +test -z $HOST_UID || (CI_USER="ci" && useradd -u $HOST_UID $CI_USER) && + +# Build and test +linux32 --32bit i386 su -m -l $CI_USER -c ' + cd /usr/src/git && + make --jobs=2 && + make --quiet test +' diff --git a/config.mak.uname b/config.mak.uname index 447f36ac2e..399fe19271 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -27,7 +27,6 @@ endif ifeq ($(uname_S),Linux) HAVE_ALLOCA_H = YesPlease NO_STRLCPY = YesPlease - NO_MKSTEMPS = YesPlease HAVE_PATHS_H = YesPlease LIBC_CONTAINS_LIBINTL = YesPlease HAVE_DEV_TTY = YesPlease @@ -41,7 +40,6 @@ endif ifeq ($(uname_S),GNU/kFreeBSD) HAVE_ALLOCA_H = YesPlease NO_STRLCPY = YesPlease - NO_MKSTEMPS = YesPlease HAVE_PATHS_H = YesPlease DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease LIBC_CONTAINS_LIBINTL = YesPlease @@ -55,7 +53,6 @@ ifeq ($(uname_S),UnixWare) SHELL_PATH = /usr/local/bin/bash NO_IPV6 = YesPlease NO_HSTRERROR = YesPlease - NO_MKSTEMPS = YesPlease BASIC_CFLAGS += -Kthread BASIC_CFLAGS += -I/usr/local/include BASIC_LDFLAGS += -L/usr/local/lib @@ -79,7 +76,6 @@ ifeq ($(uname_S),SCO_SV) SHELL_PATH = /usr/bin/bash NO_IPV6 = YesPlease NO_HSTRERROR = YesPlease - NO_MKSTEMPS = YesPlease BASIC_CFLAGS += -I/usr/local/include BASIC_LDFLAGS += -L/usr/local/lib NO_STRCASESTR = YesPlease @@ -122,7 +118,6 @@ ifeq ($(uname_S),SunOS) NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease NO_MKDTEMP = YesPlease - NO_MKSTEMPS = YesPlease NO_REGEX = YesPlease NO_MSGFMT_EXTENDED_OPTIONS = YesPlease HAVE_DEV_TTY = YesPlease @@ -168,7 +163,6 @@ ifeq ($(uname_O),Cygwin) NO_D_TYPE_IN_DIRENT = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease - NO_MKSTEMPS = YesPlease NO_SYMLINK_HEAD = YesPlease NO_IPV6 = YesPlease OLD_ICONV = UnfortunatelyYes @@ -233,7 +227,6 @@ ifeq ($(uname_S),NetBSD) BASIC_CFLAGS += -I/usr/pkg/include BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib USE_ST_TIMESPEC = YesPlease - NO_MKSTEMPS = YesPlease HAVE_PATHS_H = YesPlease HAVE_BSD_SYSCTL = YesPlease endif @@ -242,7 +235,6 @@ ifeq ($(uname_S),AIX) NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease NO_MKDTEMP = YesPlease - NO_MKSTEMPS = YesPlease NO_STRLCPY = YesPlease NO_NSEC = YesPlease FREAD_READS_DIRECTORIES = UnfortunatelyYes @@ -263,7 +255,6 @@ ifeq ($(uname_S),GNU) # GNU/Hurd HAVE_ALLOCA_H = YesPlease NO_STRLCPY = YesPlease - NO_MKSTEMPS = YesPlease HAVE_PATHS_H = YesPlease LIBC_CONTAINS_LIBINTL = YesPlease endif @@ -272,7 +263,6 @@ ifeq ($(uname_S),IRIX) NO_UNSETENV = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease - NO_MKSTEMPS = YesPlease NO_MKDTEMP = YesPlease # When compiled with the MIPSpro 7.4.4m compiler, and without pthreads # (i.e. NO_PTHREADS is set), and _with_ MMAP (i.e. NO_MMAP is not set), @@ -291,7 +281,6 @@ ifeq ($(uname_S),IRIX64) NO_UNSETENV = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease - NO_MKSTEMPS = YesPlease NO_MKDTEMP = YesPlease # When compiled with the MIPSpro 7.4.4m compiler, and without pthreads # (i.e. NO_PTHREADS is set), and _with_ MMAP (i.e. NO_MMAP is not set), @@ -311,7 +300,6 @@ ifeq ($(uname_S),HP-UX) NO_SETENV = YesPlease NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease - NO_MKSTEMPS = YesPlease NO_STRLCPY = YesPlease NO_MKDTEMP = YesPlease NO_UNSETENV = YesPlease @@ -352,7 +340,6 @@ ifeq ($(uname_S),Windows) NO_ICONV = YesPlease NO_STRTOUMAX = YesPlease NO_MKDTEMP = YesPlease - NO_MKSTEMPS = YesPlease SNPRINTF_RETURNS_BOGUS = YesPlease NO_SVN_TESTS = YesPlease RUNTIME_PREFIX = YesPlease @@ -402,7 +389,6 @@ ifeq ($(uname_S),Interix) NO_MKDTEMP = YesPlease NO_STRTOUMAX = YesPlease NO_NSEC = YesPlease - NO_MKSTEMPS = YesPlease ifeq ($(uname_R),3.5) NO_INET_NTOP = YesPlease NO_INET_PTON = YesPlease @@ -461,7 +447,6 @@ ifeq ($(uname_S),NONSTOP_KERNEL) NO_SETENV = YesPlease NO_UNSETENV = YesPlease NO_MKDTEMP = YesPlease - NO_MKSTEMPS = YesPlease # Currently libiconv-1.9.1. OLD_ICONV = UnfortunatelyYes NO_REGEX = YesPlease @@ -503,7 +488,6 @@ ifneq (,$(findstring MINGW,$(uname_S))) NEEDS_LIBICONV = YesPlease NO_STRTOUMAX = YesPlease NO_MKDTEMP = YesPlease - NO_MKSTEMPS = YesPlease NO_SVN_TESTS = YesPlease NO_PERL_MAKEMAKER = YesPlease RUNTIME_PREFIX = YesPlease @@ -515,7 +499,6 @@ ifneq (,$(findstring MINGW,$(uname_S))) OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo NO_REGEX = YesPlease NO_PYTHON = YesPlease - BLK_SHA1 = YesPlease ETAGS_TARGET = ETAGS NO_INET_PTON = YesPlease NO_INET_NTOP = YesPlease @@ -584,7 +567,6 @@ ifeq ($(uname_S),QNX) NO_ICONV = YesPlease NO_MEMMEM = YesPlease NO_MKDTEMP = YesPlease - NO_MKSTEMPS = YesPlease NO_NSEC = YesPlease NO_PTHREADS = YesPlease NO_R_TO_GCC_LINKER = YesPlease diff --git a/configure.ac b/configure.ac index 0b15f04b10..128165529f 100644 --- a/configure.ac +++ b/configure.ac @@ -1050,12 +1050,6 @@ GIT_CHECK_FUNC(mkdtemp, [NO_MKDTEMP=YesPlease]) GIT_CONF_SUBST([NO_MKDTEMP]) # -# Define NO_MKSTEMPS if you don't have mkstemps in the C library. -GIT_CHECK_FUNC(mkstemps, -[NO_MKSTEMPS=], -[NO_MKSTEMPS=YesPlease]) -GIT_CONF_SUBST([NO_MKSTEMPS]) -# # Define NO_INITGROUPS if you don't have initgroups in the C library. GIT_CHECK_FUNC(initgroups, [NO_INITGROUPS=], @@ -2870,8 +2870,25 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) s->should_free = 1; return 0; } - if (size_only) + + /* + * Even if the caller would be happy with getting + * only the size, we cannot return early at this + * point if the path requires us to run the content + * conversion. + */ + if (size_only && !would_convert_to_git(s->path)) return 0; + + /* + * Note: this check uses xsize_t(st.st_size) that may + * not be the true size of the blob after it goes + * through convert_to_git(). This may not strictly be + * correct, but the whole point of big_file_threshold + * and is_binary check being that we want to avoid + * opening the file and inspecting the contents, this + * is probably fine. + */ if ((flags & CHECK_BINARY) && s->size > big_file_threshold && s->is_binary == -1) { s->is_binary = 1; @@ -2730,8 +2730,8 @@ void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_) { struct strbuf file_name = STRBUF_INIT; struct strbuf rel_path = STRBUF_INIT; - char *git_dir = real_pathdup(git_dir_); - char *work_tree = real_pathdup(work_tree_); + char *git_dir = real_pathdup(git_dir_, 1); + char *work_tree = real_pathdup(work_tree_, 1); /* Update gitfile */ strbuf_addf(&file_name, "%s/.git", work_tree); diff --git a/environment.c b/environment.c index c07fb17fb7..42dc3106d2 100644 --- a/environment.c +++ b/environment.c @@ -259,7 +259,7 @@ void set_git_work_tree(const char *new_work_tree) return; } git_work_tree_initialized = 1; - work_tree = real_pathdup(new_work_tree); + work_tree = real_pathdup(new_work_tree, 1); } const char *get_git_work_tree(void) diff --git a/ewah/ewah_io.c b/ewah/ewah_io.c index 61f6a43579..f73210973f 100644 --- a/ewah/ewah_io.c +++ b/ewah/ewah_io.c @@ -142,8 +142,8 @@ int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len) * the endianness conversion in a separate pass to ensure * we're loading 8-byte aligned words. */ - memcpy(self->buffer, ptr, self->buffer_size * sizeof(uint64_t)); - ptr += self->buffer_size * sizeof(uint64_t); + memcpy(self->buffer, ptr, self->buffer_size * sizeof(eword_t)); + ptr += self->buffer_size * sizeof(eword_t); for (i = 0; i < self->buffer_size; ++i) self->buffer[i] = ntohll(self->buffer[i]); diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 982593c89e..f5c816e273 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -92,7 +92,7 @@ sub colored { } # command line options -my $cmd; +my $patch_mode_only; my $patch_mode; my $patch_mode_revision; @@ -1299,7 +1299,7 @@ sub patch_update_cmd { } return 0; } - if ($patch_mode) { + if ($patch_mode_only) { @them = @mods; } else { @@ -1721,7 +1721,7 @@ sub process_args { die sprintf(__("invalid argument %s, expecting --"), $arg) unless $arg eq "--"; %patch_mode_flavour = %{$patch_modes{$patch_mode}}; - $cmd = 1; + $patch_mode_only = 1; } elsif ($arg ne "--") { die sprintf(__("invalid argument %s, expecting --"), $arg); @@ -1758,7 +1758,7 @@ sub main_loop { process_args(); refresh(); -if ($cmd) { +if ($patch_mode_only) { patch_update_cmd(); } else { diff --git a/git-compat-util.h b/git-compat-util.h index ef6d560e15..e626851fe9 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -639,11 +639,6 @@ extern int gitsetenv(const char *, const char *, int); extern char *gitmkdtemp(char *); #endif -#ifdef NO_MKSTEMPS -#define mkstemps gitmkstemps -extern int gitmkstemps(char *, int); -#endif - #ifdef NO_UNSETENV #define unsetenv gitunsetenv extern void gitunsetenv(const char *); diff --git a/http-walker.c b/http-walker.c index b34b6ace7c..507c200f00 100644 --- a/http-walker.c +++ b/http-walker.c @@ -296,13 +296,16 @@ static void process_alternates_response(void *callback_data) okay = 1; } } - /* skip "objects\n" at end */ if (okay) { struct strbuf target = STRBUF_INIT; strbuf_add(&target, base, serverlen); - strbuf_add(&target, data + i, posn - i - 7); - - if (is_alternate_allowed(target.buf)) { + strbuf_add(&target, data + i, posn - i); + if (!strbuf_strip_suffix(&target, "objects")) { + warning("ignoring alternate that does" + " not end in 'objects': %s", + target.buf); + strbuf_release(&target); + } else if (is_alternate_allowed(target.buf)) { warning("adding alternate object store: %s", target.buf); newalt = xmalloc(sizeof(*newalt)); @@ -109,7 +109,7 @@ static int curl_save_cookies; struct credential http_auth = CREDENTIAL_INIT; static int http_proactive_auth; static const char *user_agent; -static int curl_empty_auth; +static int curl_empty_auth = -1; enum http_follow_config http_follow_config = HTTP_FOLLOW_INITIAL; @@ -125,6 +125,14 @@ static struct credential cert_auth = CREDENTIAL_INIT; static int ssl_cert_password_required; #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY static unsigned long http_auth_methods = CURLAUTH_ANY; +static int http_auth_methods_restricted; +/* Modes for which empty_auth cannot actually help us. */ +static unsigned long empty_auth_useless = + CURLAUTH_BASIC +#ifdef CURLAUTH_DIGEST_IE + | CURLAUTH_DIGEST_IE +#endif + | CURLAUTH_DIGEST; #endif static struct curl_slist *pragma_header; @@ -333,7 +341,10 @@ static int http_options(const char *var, const char *value, void *cb) return git_config_string(&user_agent, var, value); if (!strcmp("http.emptyauth", var)) { - curl_empty_auth = git_config_bool(var, value); + if (value && !strcmp("auto", value)) + curl_empty_auth = -1; + else + curl_empty_auth = git_config_bool(var, value); return 0; } @@ -382,10 +393,37 @@ static int http_options(const char *var, const char *value, void *cb) return git_default_config(var, value, cb); } +static int curl_empty_auth_enabled(void) +{ + if (curl_empty_auth >= 0) + return curl_empty_auth; + +#ifndef LIBCURL_CAN_HANDLE_AUTH_ANY + /* + * Our libcurl is too old to do AUTH_ANY in the first place; + * just default to turning the feature off. + */ +#else + /* + * In the automatic case, kick in the empty-auth + * hack as long as we would potentially try some + * method more exotic than "Basic" or "Digest". + * + * But only do this when this is our second or + * subsequent request, as by then we know what + * methods are available. + */ + if (http_auth_methods_restricted && + (http_auth_methods & ~empty_auth_useless)) + return 1; +#endif + return 0; +} + static void init_curl_http_auth(CURL *result) { if (!http_auth.username || !*http_auth.username) { - if (curl_empty_auth) + if (curl_empty_auth_enabled()) curl_easy_setopt(result, CURLOPT_USERPWD, ":"); return; } @@ -1079,7 +1117,7 @@ struct active_request_slot *get_active_slot(void) #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods); #endif - if (http_auth.password || curl_empty_auth) + if (http_auth.password || curl_empty_auth_enabled()) init_curl_http_auth(slot->curl); return slot; @@ -1347,6 +1385,10 @@ static int handle_curl_result(struct slot_results *results) } else { #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE; + if (results->auth_avail) { + http_auth_methods &= results->auth_avail; + http_auth_methods_restricted = 1; + } #endif return HTTP_REAUTH; } @@ -1727,6 +1769,9 @@ static int http_request_reauth(const char *url, { int ret = http_request(url, result, target, options); + if (ret != HTTP_OK && ret != HTTP_REAUTH) + return ret; + if (options && options->effective_url && options->base_url) { if (update_url_from_redirect(options->base_url, url, options->effective_url)) { diff --git a/line-log.c b/line-log.c index 65f3558b3b..a23b910471 100644 --- a/line-log.c +++ b/line-log.c @@ -43,9 +43,10 @@ void range_set_release(struct range_set *rs) static void range_set_copy(struct range_set *dst, struct range_set *src) { range_set_init(dst, src->nr); - memcpy(dst->ranges, src->ranges, src->nr*sizeof(struct range_set)); + COPY_ARRAY(dst->ranges, src->ranges, src->nr); dst->nr = src->nr; } + static void range_set_move(struct range_set *dst, struct range_set *src) { range_set_release(dst); @@ -144,7 +145,7 @@ void sort_and_merge_range_set(struct range_set *rs) static void range_set_union(struct range_set *out, struct range_set *a, struct range_set *b) { - int i = 0, j = 0, o = 0; + int i = 0, j = 0; struct range *ra = a->ranges; struct range *rb = b->ranges; /* cannot make an alias of out->ranges: it may change during grow */ @@ -167,16 +168,15 @@ static void range_set_union(struct range_set *out, new = &rb[j++]; if (new->start == new->end) ; /* empty range */ - else if (!o || out->ranges[o-1].end < new->start) { + else if (!out->nr || out->ranges[out->nr-1].end < new->start) { range_set_grow(out, 1); - out->ranges[o].start = new->start; - out->ranges[o].end = new->end; - o++; - } else if (out->ranges[o-1].end < new->end) { - out->ranges[o-1].end = new->end; + out->ranges[out->nr].start = new->start; + out->ranges[out->nr].end = new->end; + out->nr++; + } else if (out->ranges[out->nr-1].end < new->end) { + out->ranges[out->nr-1].end = new->end; } } - out->nr = o; } /* diff --git a/progress.c b/progress.c index 76a88c573f..29378caa05 100644 --- a/progress.c +++ b/progress.c @@ -243,21 +243,18 @@ void stop_progress_msg(struct progress **p_progress, const char *msg) *p_progress = NULL; if (progress->last_value != -1) { /* Force the last update */ - char buf[128], *bufp; - size_t len = strlen(msg) + 5; + char *buf; struct throughput *tp = progress->throughput; - bufp = (len < sizeof(buf)) ? buf : xmallocz(len); if (tp) { unsigned int rate = !tp->avg_misecs ? 0 : tp->avg_bytes / tp->avg_misecs; throughput_string(&tp->display, tp->curr_total, rate); } progress_update = 1; - xsnprintf(bufp, len + 1, ", %s.\n", msg); - display(progress, progress->last_value, bufp); - if (buf != bufp) - free(bufp); + buf = xstrfmt(", %s.\n", msg); + display(progress, progress->last_value, buf); + free(buf); } clear_progress_signal(); if (progress->throughput) @@ -698,7 +698,7 @@ static const char *setup_discovered_git_dir(const char *gitdir, /* --work-tree is set without --git-dir; use discovered one */ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { if (offset != cwd->len && !is_absolute_path(gitdir)) - gitdir = real_pathdup(gitdir); + gitdir = real_pathdup(gitdir, 1); if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); return setup_explicit_git_dir(gitdir, cwd, nongit_ok); @@ -806,7 +806,7 @@ static int canonicalize_ceiling_entry(struct string_list_item *item, /* Keep entry but do not canonicalize it */ return 1; } else { - char *real_path = real_pathdup(ceil); + char *real_path = real_pathdup(ceil, 0); if (!real_path) { return 0; } diff --git a/submodule.c b/submodule.c index 3b98766a6b..0a2831d846 100644 --- a/submodule.c +++ b/submodule.c @@ -1403,7 +1403,7 @@ static void relocate_single_git_dir_into_superproject(const char *prefix, /* If it is an actual gitfile, it doesn't need migration. */ return; - real_old_git_dir = real_pathdup(old_git_dir); + real_old_git_dir = real_pathdup(old_git_dir, 1); sub = submodule_from_path(null_sha1, path); if (!sub) @@ -1412,7 +1412,7 @@ static void relocate_single_git_dir_into_superproject(const char *prefix, new_git_dir = git_path("modules/%s", sub->name); if (safe_create_leading_directories_const(new_git_dir) < 0) die(_("could not create directory '%s'"), new_git_dir); - real_new_git_dir = real_pathdup(new_git_dir); + real_new_git_dir = real_pathdup(new_git_dir, 1); if (!prefix) prefix = get_super_prefix(); @@ -1472,14 +1472,14 @@ void absorb_git_dir_into_superproject(const char *prefix, new_git_dir = git_path("modules/%s", sub->name); if (safe_create_leading_directories_const(new_git_dir) < 0) die(_("could not create directory '%s'"), new_git_dir); - real_new_git_dir = real_pathdup(new_git_dir); + real_new_git_dir = real_pathdup(new_git_dir, 1); connect_work_tree_and_git_dir(path, real_new_git_dir); free(real_new_git_dir); } else { /* Is it already absorbed into the superprojects git dir? */ - char *real_sub_git_dir = real_pathdup(sub_git_dir); - char *real_common_git_dir = real_pathdup(get_git_common_dir()); + char *real_sub_git_dir = real_pathdup(sub_git_dir, 1); + char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1); if (!starts_with(real_sub_git_dir, real_common_git_dir)) relocate_single_git_dir_into_superproject(prefix, path); diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 69174c6e31..0642ae7e6e 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -133,6 +133,15 @@ RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302] RewriteRule ^/loop-redir/x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-(.*) /$1 [R=302] RewriteRule ^/loop-redir/(.*)$ /loop-redir/x-$1 [R=302] +# redir-to/502/x?y -> really-redir-to?path=502/x&qs=y which returns 502 +# redir-to/x?y -> really-redir-to?path=x&qs=y -> x?y +RewriteCond %{QUERY_STRING} ^(.*)$ +RewriteRule ^/redir-to/(.*)$ /really-redir-to?path=$1&qs=%1 [R=302] +RewriteCond %{QUERY_STRING} ^path=502/(.*)&qs=(.*)$ +RewriteRule ^/really-redir-to$ - [R=502,L] +RewriteCond %{QUERY_STRING} ^path=(.*)&qs=(.*)$ +RewriteRule ^/really-redir-to$ /%1?%2 [R=302] + # The first rule issues a client-side redirect to something # that _doesn't_ look like a git repo. The second rule is a # server-side rewrite, so that it turns out the odd-looking diff --git a/t/t1501-work-tree.sh b/t/t1501-work-tree.sh index cc5b870e58..b06210ec5e 100755 --- a/t/t1501-work-tree.sh +++ b/t/t1501-work-tree.sh @@ -423,4 +423,12 @@ test_expect_success '$GIT_WORK_TREE overrides $GIT_DIR/common' ' ) ' +test_expect_success 'error out gracefully on invalid $GIT_WORK_TREE' ' + ( + GIT_WORK_TREE=/.invalid/work/tree && + export GIT_WORK_TREE && + test_expect_code 128 git rev-parse + ) +' + test_done diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 5ffe78e920..aaa258daa3 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -394,4 +394,22 @@ test_expect_success 'diffs can be colorized' ' grep "$(printf "\\033")" output ' +test_expect_success 'patch-mode via -i prompts for files' ' + git reset --hard && + + echo one >file && + echo two >test && + git add -i <<-\EOF && + patch + test + + y + quit + EOF + + echo test >expect && + git diff --cached --name-only >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4035-diff-quiet.sh b/t/t4035-diff-quiet.sh index 461f4bb583..2f1737fcef 100755 --- a/t/t4035-diff-quiet.sh +++ b/t/t4035-diff-quiet.sh @@ -152,4 +152,13 @@ test_expect_success 'git diff --quiet ignores stat-change only entries' ' test_expect_code 1 git diff --quiet ' +test_expect_success 'git diff --quiet on a path that need conversion' ' + echo "crlf.txt text=auto" >.gitattributes && + printf "Hello\r\nWorld\r\n" >crlf.txt && + git add .gitattributes crlf.txt && + + printf "Hello\r\nWorld\n" >crlf.txt && + git diff --quiet crlf.txt +' + test_done diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index 9d87777b59..d0377fae5c 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -106,4 +106,14 @@ test_expect_success '-L with --output' ' test_line_count = 70 log ' +test_expect_success 'range_set_union' ' + test_seq 500 > c.c && + git add c.c && + git commit -m "many lines" && + test_seq 1000 > c.c && + git add c.c && + git commit -m "modify many lines" && + git log $(for x in $(test_seq 200); do echo -L $((2*x)),+1:c.c; done) +' + test_done diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index aeb3a63f7c..2d3b1e9f93 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -378,5 +378,14 @@ test_expect_success 'http-alternates triggers not-from-user protocol check' ' clone $HTTPD_URL/dumb/evil.git evil-user ' +test_expect_success 'can redirect through non-"info/refs?service=git-upload-pack" URL' ' + git clone "$HTTPD_URL/redir-to/dumb/repo.git" +' + +test_expect_success 'print HTTP error when any intermediate redirect throws error' ' + test_must_fail git clone "$HTTPD_URL/redir-to/502" 2> stderr && + test_i18ngrep "unable to access.*/redir-to/502" stderr +' + stop_httpd test_done diff --git a/transport.c b/transport.c index d72e089484..b6c5652d6c 100644 --- a/transport.c +++ b/transport.c @@ -1221,7 +1221,7 @@ static int refs_from_alternate_cb(struct alternate_object_database *e, const struct ref *extra; struct alternate_refs_data *cb = data; - other = real_pathdup(e->path); + other = real_pathdup(e->path, 1); len = strlen(other); while (other[len-1] == '/') diff --git a/worktree.c b/worktree.c index d633761575..0486e31ad4 100644 --- a/worktree.c +++ b/worktree.c @@ -255,7 +255,7 @@ struct worktree *find_worktree(struct worktree **list, return wt; arg = prefix_filename(prefix, strlen(prefix), arg); - path = real_pathdup(arg); + path = real_pathdup(arg, 1); for (; *list; list++) if (!fspathcmp(path, real_path((*list)->path))) break; @@ -440,23 +440,6 @@ int xmkstemp(char *template) return fd; } -/* git_mkstemp() - create tmp file honoring TMPDIR variable */ -int git_mkstemp(char *path, size_t len, const char *template) -{ - const char *tmp; - size_t n; - - tmp = getenv("TMPDIR"); - if (!tmp) - tmp = "/tmp"; - n = snprintf(path, len, "%s/%s", tmp, template); - if (len <= n) { - errno = ENAMETOOLONG; - return -1; - } - return mkstemp(path); -} - /* Adapted from libiberty's mkstemp.c. */ #undef TMP_MAX @@ -531,13 +514,6 @@ int git_mkstemp_mode(char *pattern, int mode) return git_mkstemps_mode(pattern, 0, mode); } -#ifdef NO_MKSTEMPS -int gitmkstemps(char *pattern, int suffix_len) -{ - return git_mkstemps_mode(pattern, suffix_len, 0600); -} -#endif - int xmkstemp_mode(char *template, int mode) { int fd; diff --git a/wt-status.c b/wt-status.c index d47012048f..234e77a6d6 100644 --- a/wt-status.c +++ b/wt-status.c @@ -1730,12 +1730,14 @@ static void wt_shortstatus_print_tracking(struct wt_status *s) return; branch_name = s->branch; +#define LABEL(string) (s->no_gettext ? (string) : _(string)) + if (s->is_initial) - color_fprintf(s->fp, header_color, _("Initial commit on ")); + color_fprintf(s->fp, header_color, LABEL(N_("Initial commit on "))); if (!strcmp(s->branch, "HEAD")) { color_fprintf(s->fp, color(WT_STATUS_NOBRANCH, s), "%s", - _("HEAD (no branch)")); + LABEL(N_("HEAD (no branch)"))); goto conclude; } @@ -1760,8 +1762,6 @@ static void wt_shortstatus_print_tracking(struct wt_status *s) if (!upstream_is_gone && !num_ours && !num_theirs) goto conclude; -#define LABEL(string) (s->no_gettext ? (string) : _(string)) - color_fprintf(s->fp, header_color, " ["); if (upstream_is_gone) { color_fprintf(s->fp, header_color, LABEL(N_("gone"))); |